This is a Go program to simplify the encryption & decryption of byte arrays, using 256 bit AES keys in Galois/Counter Mode (GCM), with cloud-based KMS services (currently only Google KMS) and multiple key layers (specifically Envelope Encryption).
Darwin, Linux and Windows Binaries can be downloaded from the Releases page.
Try it out:
$ mantle -h
$ git clone [email protected]:ovotech/mantle.git
$ cd mantle
$ go build
$ ./mantle -h
$ go get -u github.com/ovotech/mantle
You'll need to create a Key Ring and Key (if not already present) in Google KMS to allow the tool to encrypt/decrypt.
If you have gcloud set up locally, and your user has the Cloud KMS CryptoKey Encrypter and/or Cloud KMS CryptoKey Decrypter Role(s), the tool will
already be able to encrypt/decrypt.
If you're running the binary in an automated way (i.e. with a Service Account):
GOOGLE_APPLICATION_CREDENTIALS env var as the path of the key.jsonThe final piece of the puzzle is obtaining the name of the KMS Key the tool is going to use.
Using gcloud, you can do this by issuing:
# get the name of the Keyring that 'holds' the required Key
$ gcloud kms keyrings list --location <location>
# get the name of the Key
$ gcloud kms keys list --location <location> --keyring <keyring_name>
The NAME value returned by the last command is Google's Resource ID for the
Key. It's this value that you can give to the mantle binary in the
-n,--keyName flag, to get it to work.
Alternatively to using gcloud you can get the Resource ID from the Google Cloud Console; click on the KeyRing
you want to use, and select "Copy Resource ID" from the menu to the right of the
correct Key.
The key name string can be pretty long, as there's various things being referenced within them. It will be in the following format:
projects/<project_name>/locations/<location>/keyRings/<keyring_name>/cryptoKeys/<key_name>
To test this out, you should be able to:
# create plain.text
$ echo "helloworld" > plain.txt
# issue the encrypt command. The binary should output to command line the
# encrypted string, remove the plain.txt file, and create a cipher.txt file
$ mantle encrypt -n <key_name>
# take a look at the cipher.txt
$ cat cipher.txt
# now we can decrypt back again, you should be left with a new plain.txt
$ mantle decrypt -n <key_name>
$ cat plain.txt
A new 256-bit AES key and a 96-bit nonce are generated every time you issue
the encrypt command. The key and nonce are used to encrypt your plaintext.
The AES key, also known as the Data Encryption Key (DEK), is then encrypted using the Cloud KMS Service.
The concatenated encrypted data, nonce and encrypted DEK are then given back to the user as the ciphertext.
Decrypting is the same process but in reverse.
The structure of a ciphertext will be:
encryptedData[n]nonce[12]encryptedDEK[113]
The encrypted DEK is 113 chars. This is the length of the string returned by Google KMS after it's been base64 decoded. The length of the encrypted data will depend on the length of your plaintext.
When encrypting, newline chars are by default inserted into the ciphertext,
every 40 chars. This is to play nicer with any max line lengths when storing in
source code. This functionality can be disabled using the -s, --singleLine
flag.
So long as the decrypting process is only removing newline chars at the end of lines, it shouldn't need to differentiate the two 'modes'
Mantle uses the crypto/rand Reader to
generate a new IV every time the encrypt command is called.
"Reader is a global, shared instance of a cryptographically secure random number generator.
On Linux, Reader uses getrandom(2) if available, /dev/urandom otherwise. On OpenBSD, Reader uses getentropy(2). On other Unix-like systems, Reader reads from /dev/urandom. On Windows systems, Reader uses the CryptGenRandom API. On Wasm, Reader uses the Web Crypto API."
The IV is created by reading 96 bits (12 bytes) from this Reader.
By default, when performing either encrypt or decrypt commands, the tool
will zero-fill and delete the source file, so plain.txt or cipher.txt (or an
overriding filepath you've set) respectively.
When decrypting, you can use the -r,--retainCipherText flag in order to
retain the ciphertext file. There's no option to retain the source file when
encrypting.
$ mantle encrypt -n <key_name>
Encrypting...
-----BEGIN (ENCRYPTED DATA + DEK) STRING-----
y+PvJrf0QJKKSp85C0MN6q2v7EhMeorNJG+5FLiN
wV/Wow6eWHFL80x3xl7vIgDVN5CdRAOVpZL2kJV3
coDbctszL5LJHaLL22YVYaJwojETz5Aff4Kss98p
MIRahCJ1D8EFNoBbTAQTUGNJAJGc11YcX3sWpsYB
h3BookBa6KEvnmNFfw8F6M71zpdmByS1p/k8/1Z/
TAX/Dj0wxcm2g/ez7gA0e/vFQXQjJYqSkb0xJuQX
SVaDoXap3HF7NbikcklBPBkDvy408Hogapvh4OF2
vL9tlhGoERUkrWcwXQfcZjk1B3Sjh45UDTHySTs+
m4Eco7MOur6LvfrGKJuX6qJubppxUDv2ZTCeMCrK
d9AjmCqleD/iSthZN1FKjQ3zLowlnsvWIMnaeEC+
h5W8NIjKm4YQCY2yGj3V6AhdBMvujXLX1aYbIHSf
GfIzLhHSKI7vUm0RFN5irblcoC+sBkRf8NAKJAB1
PbjZJT8wZ94zMUnqrUNNCJqzoky5PFiAY0x077co
SHATyRJJAOR2fnkCjptlffrP0/y8Jhs7ogtttzwt
mkJtdbf9ltQw2ak1OJI3h7NC9vLqfDzGQFeO396C
RRt3E3ly9MifB+cFe4Fnowcq0g==
-----END (ENCRYPTED DATA + DEK) STRING-----
Encryption successful, ciphertext available at ./cipher.txt
Wiped 340 bytes from ./plain.txt.
Your ciphertext is the string between (not including) the BEGIN and END
markers. The resulting cipher.txt file will only contain the ciphertext
string.
Contributions are very welcome, please fork or branch and raise a PR.
Content type
Image
Digest
Size
148.1 MB
Last updated
about 5 years ago
docker pull ovotech/mantle