Sign inSign up

ovotech/mantle

By ovotech

•Updated about 5 years ago

Automated build for ovotech/mantle

Image
0

50K+

ovotech/mantle repository overview

⁠Mantle

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⁠).

⁠Install

⁠From Binary Releases

Darwin, Linux and Windows Binaries can be downloaded from the Releases page⁠.

Try it out:

$ mantle -h
⁠From Source
$ git clone [email protected]:ovotech/mantle.git

$ cd mantle

$ go build

$ ./mantle -h
⁠As a Go Dependency
$ go get -u github.com/ovotech/mantle

⁠Getting Started

⁠GCP

You'll need to create a Key Ring and Key⁠ (if not already present) in Google KMS to allow the tool to encrypt/decrypt.

⁠Authorisation

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):

  • The Service Account will need the Cloud KMS CryptoKey Encrypter and/or Decrypter Role(s
  • Drop the Service Account's key.json onto the host you're running the tool on
  • Set the GOOGLE_APPLICATION_CREDENTIALS env var as the path of the key.json
⁠Obtain The Key's Resource ID

The 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

⁠How It Works

  1. 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.

  2. The AES key, also known as the Data Encryption Key (DEK), is then encrypted using the Cloud KMS Service.

  3. 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.

⁠Ciphertext Structure

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.

⁠Notes

⁠Newlines

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'

⁠IV

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.

⁠Zero-fill and Delete

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.

⁠Example

$ 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.

⁠Contributing

Contributions are very welcome, please fork or branch and raise a PR.

Tag summary

Content type

Image

Digest

Size

148.1 MB

Last updated

about 5 years ago

docker pull ovotech/mantle