Skip to content

Filesystem Keystore

Andreas Auernhammer edited this page Mar 7, 2022 · 25 revisions

This guide shows how to setup a KES server that uses the filesystem as persistent key store. A plain filesystem does not provide any protection for the stored keys. It should only be used for testing purposes.

                         ╔══════════════════════════════════════════╗
┌────────────┐           ║  ┌────────────┐          ┌────────────┐  ║
│ KES Client ├───────────╫──┤ KES Server ├──────────┤ Filesystem │  ║
└────────────┘           ║  └────────────┘          └────────────┘  ║
                         ╚══════════════════════════════════════════╝

KES Server setup

First, we need to generate a TLS private key and certificate for our KES server. A KES server can only be run with TLS - since secure-by-default. Here we use self-signed certificates for simplicity. For a production setup we highly recommend to use a certificate signed by CA (e.g. your internal CA or a public CA like Let's Encrypt)

  1. Generate a TLS private key and certificate for the KES server.
    The following command will generate a new TLS private key server.key and a X.509 certificate server.cert that is self-signed and issued for the IP 127.0.0.1 and DNS name localhost (as SAN). You may want to customize the command to match your setup.

    $ kes identity new --ip "127.0.0.1" localhost
    
      Private key:  private.key
      Certificate:  public.crt
      Identity:     2e897f99a779cf5dd147e58de0fe55a494f546f4dcae8bc9e5426d2b5cd35680

    Any other tooling for X.509 certificate generation works as well. For example, you could use openssl:

    $ openssl ecparam -genkey -name prime256v1 | openssl ec -out private.key
    
    $ openssl req -new -x509 -days 30 -key private.key -out public.crt \
       -subj "/C=/ST=/L=/O=/CN=localhost" -addext "subjectAltName = IP:127.0.0.1"
    
  2. Then, create a private key and certificate for your application:

    $ kes identity new --key=client.key --cert=client.crt MyApp
    
      Private key:  client.key
      Certificate:  client.crt
      Identity:     02ef5321ca409dbc7b10e7e8ee44d1c3b91e4bf6e2198befdebee6312745267b

    The identity new command will print the identity of your client.crt.
    You can re-compute the identity anytime via: $ kes identity of client.crt.

  3. Now we have defined all entities in our demo setup. Let's wire everything together by creating the config file server-config.yml:

    address: 0.0.0.0:7373
    admin:
      identity: disabled  # We disable the admin identity since we don't need it in this guide 
    
    tls:
      key: private.key
      cert: public.crt
    
    policy:
      my-app: 
        allow:
        - /v1/key/create/my-app-key*
        - /v1/key/generate/my-app-key*
        - /v1/key/decrypt/my-app-key*
        identities:
        - 02ef5321ca409dbc7b10e7e8ee44d1c3b91e4bf6e2198befdebee6312745267b # Use the identity of your client.crt
    
    keystore:
      fs:
        path: ./keys # Choose a directory for the secret keys
  4. Finally we can start a KES server in a new window/tab:

    $ kes server --config=server-config.yml --auth=off

    --auth=off is required since our client.crt certificate is self-signed

  5. In the previous window/tab we now can connect to the server by:

    export KES_CLIENT_CERT=client.crt
    export KES_CLIENT_KEY=client.key
    kes key create my-app-key -k

    -k is required because we use self-signed certificates

    Now, you should see a secret key inside the ./keys directory.

  6. Finally, we can derive and decrypt data keys from the previously created my-app-key:

    $ kes key derive my-app-key -k
    {
      plaintext : ...
      ciphertext: ...
    }
    $ kes key decrypt my-app-key <base64-ciphertext> -k
    
      plaintext : ...
Clone this wiki locally