GO - Key Management Service
A REST based Key Management Service written in GO.
What is GO-KMS?
GO-KMS is a encryption Key Management Service in GO. Modelled extensively on AWS KMS behaviour, the API is used for symmetrical key management. It offers Cryptography as a Service (CaaS) functionality such as encryption/decryption/reencryption without exposing keys.
Keys are encrypted and stored on disk, using a master key which is derived using PBKDF2 from a passphrase when run in pure software mode. It is also possible to combine GO-KMS with a Hardware Security Module (HSM) which can be leveraged to create and encrypt a master key using the HSM for generation and protection. HSM support is done using the PKCS#11 standard.
GO-KMS authentication is done using HMAC-SHA256 over HTTPS.
GO-KMS - Command Line Interface
GO-KMS-CLI is a command line interface which can be used to manage and interact with go-kms. The project can be found here: https://github.com/keithballdotnet/go-kms-cli
- AES Key store
- Cryptography as a Service
- Keys encrypted while at rest
- Shared-key Authentication
- Playground for HSM support via SoftHSM2 and PKCS#11
- Some documentation about the keys
- RSA Encryption provider
- Automatic key rotation?
- Full HSM provider support
To run get the project...
go get github.com/keithballdotnet/go-kms
The dependencies are in the vendor folder already, but should you want to you can run ...
You need to set the following variables:
export GOKMS_AUTH_KEY=/path/to/auth.key export GOKMS_CRYPTO_PROVIDER= hsm | gokms export GOKMS_HOST=localhost export GOKMS_PORT=8020 export GOKMS_SSL_CERT=/path/to/ssl_cert.pem export GOKMS_SSL_KEY=/path/to/ssl_key.pem
If the GOKMS_CRYPTO_PROVIDER is set to "gokms" then you also need to set:
export GOKMS_KSMC_PATH=/path/to/keys/ export GOKMS_KSMC_PASSPHRASE="a very long Passphrase that will be used for key derivation"
If the GOKMS_CRYPTO_PROVIDER is set to "hsm" then you also need to set:
export GOKMS_HSM_LIB=/path/to/your/hsm/lib.so export GOKMS_HSM_SLOT="0" export GOKMS_HSM_AES_KEYID="TheNameOfTheCryptoKey" # optional: If not set no pkcs11 login will be performed. Useful for Tokens with no PIN set. export GOKMS_HSM_SLOT_PIN="1234"
Authorization is done via a Authorization header sent in a request. Anonymous requests are not allowed. To authenticate a request, you must sign the request with the shared key when making the request and pass that signature as part of the request.
Here you can see an example of a Authorization header
You construct the signature is built in the following format:
authRequestSig = method + "\n" + Date + "\n" + resource
This would result in the following signature to be signed:
POST\nWed, 28 Jan 2015 10:42:13 UTC\n/api/v1/go-ksm
Note that you MUST past the same date value in the request. Date should be supplied in UTC using RFC1123 format.
x-kms-date=Wed, 28 Jan 2015 10:42:13 UTC
The signature must be exactly in the same order and include the new line character.
Now encode the signature using the HMAC-SHA256 algorithm using the shared key.
This will result in a key like this:
Example go code to create the signature
date := time.Now().UTC().Format(time.RFC1123) // UTC time request.Header.Add("x-kms-date", date) authRequestKey := fmt.Sprintf("%s\n%s\n%s", method, date, resource) // See package http://golang.org/pkg/crypto/hmac/ on how golang creates hmacs hmac := crypto.GetHmac256(authRequestKey, SharedKey) request.Header.Add("Authorization", hmac)
- AWS KMS: https://d0.awsstatic.com/whitepapers/KMS-Cryptographic-Details.pdf
- MS Key Vault: https://msdn.microsoft.com/en-US/library/azure/dn903623
- SofthHsm2 only supports RSA encryption: https://wiki.opendnssec.org/display/SoftHSM/v2+Requirements
Install notes if building SofthHsm2 support:
Add some missing things needed to build, pkcs11
sudo yum install libtool-ltdl-devel
sudo yum-config-manager --add-repo http://copr-fe.cloud.fedoraproject.org/coprs/pspacek/softhsm2/ sudo yum install softhsm2
Create a place to store the tokens
Create/change config file to reflect new token location
# SoftHSM v2 configuration file directories.tokendir = /home/keithball/Documents/tokens objectstore.backend = file # ERROR, WARNING, INFO, DEBUG log.level = DEBUG
Create initial token...
export SOFTHSM2_CONF=$PWD/softhsm2.conf softhsm2-util --init-token --slot 0 --label "My token 1"
Check it worked ok