Logo

github Download
Key generation

Key generation #

During the initial setup of Acra you will need to generate new keys for all components involved.

  1. Acra Master Key(s).

  2. Storage keys and searchable encryption keys.

    At least for one client ID or zone ID. Storage keys are the ones responsible for data encryption. There are two kinds of crypto containers (AcraStructs and AcraBlocks) and two different kinds of keys for them (storage symmetric keys and storage asymmetric keys).

    Searchable encryption keys are used for searchable encryption functionality as it speaks for itself.

  3. Transport keys.

    Transport keys support is deprecated and will not be available since 0.91.0. Use TLS instead.

    If TLS is used, then key/certificate generation is out of this topic’s scope, although you can get some hints on certificate generation page.

    If you decided to use AcraConnector with Themis Secure Session, you will need Themis Secure Session transport keys for both AcraConnector and AcraServer/AcraTranslator.

  4. Exchange public keys between components.

Acra Master Keys #

Acra uses many cryptographic keys; most of them are private and thus stored in encrypted form. There are very special Acra Master Keys that are used by each Acra component to decrypt private keys as necessary. Look after the master keys very carefully!

If you lose them, all your data is gone.

Note: Due to security reasons, AcraConnectors always need to have different Acra Master Keys.

AcraServer and AcraTranslator need to have different Acra Master Keys when they are working with independent databases / sets of data.

Current keystore version 1 uses one master key called ACRA_MASTER_KEY. It is used only to encrypt the stored private keys.

New keystore version 2 uses two distinct master keys: one is used to encrypt private key material, the other one is used to sign public keystore data. Both of them are still encoded as a single ACRA_MASTER_KEY value.

1. Setting up AcraServer or AcraTranslator #

Keys for AcraServer and AcraTranslator are generated in the same fashion.

1.1. Generating Acra Master Key #

Use acra-keymaker utility to generate a new master key and save it into a file.

By default, Acra components retrieve master keys from environment variables as base64-encoded strings.

Generate a new key and assign it to the environment variable on the corresponding server:

acra-keymaker --keystore=v1 --generate_master_key=master.key

export ACRA_MASTER_KEY=$(cat master.key | base64)

With keystore version 2 you will need to use acra-keymaker --keystore=v2.

Note: If you are using Acra 0.85 or earlier, please omit the --keystore parameter here and onward.

Put Acra Master Key to KMS #

By default, Acra components retrieve master keys from environment variables as base64-encoded strings.

We recommend generating Acra Master Key and storing it in KMS. Refer to Configuring and maintaining to learn how to integrate KMS.

1.2. Generating transport and encryption keys #

After you set up the master keys, all private keys generated by acra-keymaker will be encrypted before they are written to disk.

Now, let’s generate keypairs for Acra’s components:

acra-keymaker --client_id=Alice \
  --generate_acraserver_keys \
  --generate_acratranslator_keys \
  --generate_acrawriter_keys \
  --generate_acrawebconfig_keys \
  --generate_symmetric_storage_key \
  --generate_hmac_key \
  --generate_log_key

You can learn more about what each flag means by reading acra-keymaker docs

Carry out these operations on the machine running AcraServer or AcraTranslator to make sure that the private keys for Acra never leak outside from the server.

acra-keymaker will generate and place the resulting keys into the .acrakeys directory (you can change the name with the --keys_output_dir option):

.acrakeys
├── .poison_key
│   └── poison_key.pub
│   └── poison_key
│   └── poison_key_sym
├── auth_key
├── secure_log_key
├── Alice_server
├── Alice_server.pub
├── Alice_storage
├── Alice_storage.pub
├── Alice_storage_sym
├── Alice_hmac
├── Alice_translator
└── Alice_translator.pub

Note: Stored keys should not be world-readable. acra-keymaker creates keys with proper access permissions:

  • rwx------ (700) for .acrakeys directory
  • rw------- (600) for private key files

AcraServer and AcraTranslator check this and will refuse to launch if access to the keys is not properly restricted.

auth_key and transport keys are deprecated and will not be used since 0.91.0.

If you are running Acra 0.86+ and wish to try the new keystore version 2, use --keystore=v2 option when generating the keys:

acra-keymaker --keystore=v2 \
  --client_id=Alice \
  --generate_acraserver_keys \
  --generate_acratranslator_keys \
  --generate_acrawriter_keys \
  --generate_acrawebconfig_keys \
  --generate_symmetric_storage_key \
  --generate_hmac_key \
  --generate_log_key

In this case the directory layout will be a bit different:

.acrakeys
├── authentication.keyring
├── audit-log.keyring
├── client
│   └── Alice
│       ├── storage.keyring
│       ├── storage-sym.keyring
│       ├── hmac-sym.keyring
│       └── transport
│           ├── server.keyring
│           └── translator.keyring
└── version
authentication.keyring and transport keyrings are deprecated and will not be used since 0.91.0.

2. Setting up AcraConnector (optional) #

AcraConnector is deprecated and will not be available since 0.91.0. Use TLS instead.

This step is required only if you are using AcraConnector in Themis Secure Session mode to provide reliable transport encryption between client app and AcraServer/AcraTranslator.

2.1. Generating master keys #

Generate a second set of master keys for AcraConnector in the same way, but on the server that runs AcraConnector:

acra-keymaker --keystore=v1 --generate_master_key=master.key

export ACRA_MASTER_KEY=$(cat master.key | base64)

(Or with --keystore=v2 to set up for keystore version 2.)

Note: If you are using Acra 0.85 or earlier, please omit the --keystore parameter here and onward.

2.2. Generating transport keys #

Similarly, generate transport key for AcraConnector:

acra-keymaker --keystore=v1 --client_id=Alice --generate_acraconnector_keys

Carry out this operation on the machine running AcraConnector to make sure that the private key of AcraConnector never leaks outside it.

acra-keymaker will generate and place 2 keys into the .acrakeys directory (you can change the name with the --keys_output_dir option):

.acrakeys
├── Alice
└── Alice.pub

Note: Stored keys should not be world-readable. acra-keymaker creates keys with proper access permissions:

  • rwx------ (700) for .acrakeys directory
  • rw------- (600) for private key files

AcraConnector checks this and will refuse to launch if access to the keys is not properly restricted.

If you are running Acra 0.86+ and wish to try the new keystore version 2, use --keystore=v2 option when generating the keys:

acra-keymaker --keystore=v2 --client_id=Alice --generate_acraconnector_keys

In this case the resulting directory layout will be a bit different:

.acrakeys
├── client
│   └── Alice
│       └── transport
│           └── connector.keyring
└── version

3. Exchanging public keys (optional) #

Components that need to communicate should have each other’s public key. This allows the components to authenticate each other when establishing a Themis Secure Session. AcraWriter also needs the public storage key generated by AcraServer or AcraTranslator to encrypt the user data for storage.

These steps are required only if you are using client-side encryption with AcraWriter, or AcraConnector to securely connect client application with AcraServer/AcraTranslator, and it uses Themis Secure Session as the transport encryption protocol.

The rules of key exchange are simple:

  • private keys should stay where they were generated
  • public keys should be shared with the peers which need to communicate

Exporting and importing keys #

Key exchange process is a bit different for current keystore version 1 and the new version 2.

With keystore version 1 you simply copy a file with *.pub extension from .acrakeys directory. For example, .acrakeys/Alice_server.pub is a public key of the client Alice on AcraServer, this file needs to be copied to corresponding .acrakeys directory of AcraConnector.

Keystore version 2 makes this process more secure by ensuring that the key file cannot be tampered while en route between the server. First, the public key has to be exported from AcraServer:

acra-keys export --key_bundle_file "encrypted-keys.dat" \
                 --key_bundle_secret "access-keys.json" \
    client/Alice/transport/server

then encrypted-keys.dat and access-keys.json files should be transferred by separate channels to AcraConnector where they are combined to import the key into the keystore:

acra-keys import --key_bundle_file "encrypted-keys.dat" \
                 --key_bundle_secret "access-keys.json"
Note: It is not possible to transfer keys of keystore version 2 by simple copying. The public key data is signed with a different key and will not be accepted.

3.1. AcraConnector and AcraServer #

Place public key of AcraServer on AcraConnector and place public key of AcraConnector on AcraServer.

Component should contain key named like this
AcraConnector transport public key of AcraServer .acrakeys/Alice_server.pub
AcraConnector transport private key of AcraConnector .acrakeys/Alice
AcraServer transport public key of AcraConnector .acrakeys/Alice.pub
AcraServer transport private key of AcraServer .acrakeys/Alice_server

With keystore version 2 you need to export the following keys:

# On AcraServer
acra-keys export --key_bundle_file "server-encrypted-keys.dat" \
                 --key_bundle_secret "server-access-keys.json" \
    client/Alice/transport/server

# On AcraConnector
acra-keys export --key_bundle_file "connector-encrypted-keys.dat" \
                 --key_bundle_secret "connector-access-keys.json" \
    client/Alice/transport/connector

# On AcraServer
acra-keys import --key_bundle_file "connector-encrypted-keys.dat" \
                 --key_bundle_secret "connector-access-keys.json"

# On AcraConnector
acra-keys import --key_bundle_file "server-encrypted-keys.dat" \
                 --key_bundle_secret "server-access-keys.json"

3.2. AcraConnector and AcraTranslator #

Place public key of AcraTranslator on AcraConnector and public key of AcraConnector on AcraTranslator.

Component should contain key named like this
AcraConnector transport public key of AcraTranslator .acrakeys/Alice_translator.pub
AcraConnector transport private key of AcraConnector .acrakeys/Alice
AcraTranslator transport public key of AcraConnector .acrakeys/Alice.pub
AcraTranslator transport private key of AcraTranslator .acrakeys/Alice_translator

With keystore version 2 you need to export the following keys:

# On AcraTranslator
acra-keys export --key_bundle_file "translator-encrypted-keys.dat" \
                 --key_bundle_secret "translator-access-keys.json" \
    client/Alice/transport/translator

# On AcraConnector
acra-keys export --key_bundle_file "connector-encrypted-keys.dat" \
                 --key_bundle_secret "connector-access-keys.json" \
    client/Alice/transport/connector

# On AcraTranslator
acra-keys import --key_bundle_file "connector-encrypted-keys.dat" \
                 --key_bundle_secret "connector-access-keys.json"

# On AcraConnector
acra-keys import --key_bundle_file "translator-encrypted-keys.dat" \
                 --key_bundle_secret "translator-access-keys.json"

3.3. AcraWriter and AcraServer or AcraTranslator #

Place public key of AcraServer or AcraTranslator to AcraWriter.

Component should contain key named like this
AcraWriter storage public key .acrakeys/Alice_storage.pub
AcraServer storage private key .acrakeys/Alice_storage
AcraTranslator storage private key .acrakeys/Alice_storage

With keystore version 2 you need to export the following keys:

# On AcraServer or AcraTranslator
acra-keys export --key_bundle_file "encrypted-keys.dat" \
                 --key_bundle_secret "access-keys.json" \
    client/Alice/storage

# On AcraWriter
acra-keys import --key_bundle_file "encrypted-keys.dat" \
                 --key_bundle_secret "access-keys.json"

If you need to access the public key in plain for AcraWriter, use acra-keys read:

acra-keys read --client_id=Alice storage-public > public-key.dat

Generating and exchanging zone keys #

Generating zone keys is different from generating usual AcraStruct encryption keys. You should run acra-addzone on AcraServer or AcraTranslator to generate a zone:

acra-addzone

This creates a new zone, and you get a JSON object like this:

{"id":"DDDDDDDDQHpbUSOgYTzqCktp","public_key":"VUVDMgAAAC3yMBGsAmK/wBXZkL8iBv/C+7hqoQtSZpYoi4fZYMafkJbWe2dL"}

AcraWriter will need both the zone ID (returned as is) and the public key (returned in base64) to generate AcraStructs for the new zone.

Zone keys are placed into the keystore too:

Component should contain key named like this
AcraWriter zone public key .acrakeys/DDDDDDDDQHpbUSOgYTzqCktp_zone.pub
AcraServer zone private key .acrakeys/DDDDDDDDQHpbUSOgYTzqCktp_zone
AcraTranslator zone private key .acrakeys/DDDDDDDDQHpbUSOgYTzqCktp_zone

With keystore version 2 you can import and export zone keys too:

# On AcraServer or AcraTranslator
acra-keys export --key_bundle_file "encrypted-keys.dat" \
                 --key_bundle_secret "access-keys.json" \
    zone/DDDDDDDDQHpbUSOgYTzqCktp/storage

# On AcraWriter
acra-keys import --key_bundle_file "encrypted-keys.dat" \
                 --key_bundle_secret "access-keys.json"