Hashicorp Vault Encryption as a Service — Tutorial

Xyz Zyx
4 min readFeb 14, 2020

--

the official vault docs are very good, but I want to write my own tutorial…so here it is

1. Let’s start nice & easy THE VAULT

create a directory somewhere where you would store couple of files

create a file vault-config.hcl

disable_cache = true
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 1
}
plugin_directory = "/YOUR_DESIRED_DIR/vault_plugins"

storage "file" {
path = "/YOUR_DESIRED_DIR/vault_data"
}

api_addr = "http://0.0.0.0:8200"
disable_mlock=true
ui = true

notice that the API is opened, and there aren’t any TLS stuff. In a production env you would use consul instead of file, and you would add a certificate

Start the server like this:

vault server -config=vault-config.hcl

(note: you probably want to start it running in the background right? I use pm2 for this, but you can use whatever you’re comfortable with

pm2 start "vault" — server -log-level=debug -config=vault-config.hcl

open a new terminal and write

export VAULT_ADDR=http://127.0.0.1:8200
vault operator init

you’ll get something like this:

                   
Unseal Key 1: iyPCt9eHn2owQ++zbdOtl8j6rwt+v+hRc3vCj9vxzb3s
Unseal Key 2: EurxzUsG5n0t29IRRCJN282xRREMhvjqXlwXoapHQj2I
Unseal Key 3: 8GCPpUv7xDFvxbQr6OmzH5OW8rdYsArnaBuXFu7qK8nG
Unseal Key 4: u26/w5Q48+/PcBE/Ik9D9qh5xs/qvBv9zdDp3BpY+UbE
Unseal Key 5: WvJZ9I+cvtthJ5dUVfY7RLNaSFtF/LMbOPw6R2nPRZSE

Initial Root Token: s.PNWPCnJlczDVD2G6gRUeTTs7

copy them to a separate file from now (you won’t do this in a production environment) then proceed to unseal the vault

When a Vault server is started, it starts in a sealed state. In this state, Vault is configured to know where and how to access the physical storage, but doesn’t know how to decrypt any of it.

Unsealing is the process of constructing the master key necessary to read the decryption key to decrypt the data, allowing access to the Vault.

The data stored by Vault is stored encrypted. Vault needs the encryption key in order to decrypt the data. The encryption key is also stored with the data, but encrypted with another encryption key known as the master key. The master key isn’t stored anywhere.

Therefore, to decrypt the data, Vault must decrypt the encryption key which requires the master key. Unsealing is the process of reconstructing this master key.

vault operator unseal [PASTE HERE THE Unseal Key 1 that you got]

vault operator unseal [PASTE HERE THE Unseal Key 2 that you got]

vault operator unseal [PASTE HERE THE Unseal Key 2 that you got]

then for convenience (you won’t do this in a production environment)

export VAULT_ROOT_TOKEN=[PASTE HERE THE Initial Root Token that you got]

now remember you put ui = true in the config file

open up a browser at http://127.0.0.1:8200/ui and you should be presented with a nice “Sign in to Vault” page.

You can congratulate yourself if you reached this far. Most people don’t, but you’re not like most people right ?

— — — — — — —

2. Enable Encryption as a Service

Note: all this commands below can be done via API calls using curl for example or via web ui.

login in vault with

vault login $VAULT_ROOT_TOKEN

The transit secrets engine must be configured before it can perform its operations.

and enable the “transit’ secrets

vault secrets enable transit

now you must create what they call an encryption key ring by executing. A key Ring is used every time you rotate the keys, but let’s not worry about it for now

vault write -f transit/keys/transactions

you should get a output message

Success! Data written to: transit/keys/transactions

3. Encrypt Data

Now in order to write a plaintext secret, you need to convert that secret into base64. If you’re on linux then you can just use

base64 <<< "Jon,Snow,4111 1111 1111 1111,restaurant,$100,1892030903" 
Sm9uLFNub3csNDExMSAxMTExIDExMTEgMTExMSxyZXN0YXVyYW50LCwxODkyMDMwOTAzCg==

that returns:

Sm9uLFNub3csNDExMSAxMTExIDExMTEgMTExMSxyZXN0YXVyYW50LCwxODkyMDMwOTAzCg==

(if you’re not on Linux you can use the web ui by going to Tools -> Hash and you have a small button there “Encode to base64”)

so to push this secret into the vault you can do

option #1. Command line

vault write transit/encrypt/transactions plaintext=$(base64 <<< "Jon,Snow,4111 1111 1111 1111,restaurant,$100,1892030903")
Key Value
--- -----
ciphertext vault:v1:2QcEVS3oeNvhwNq36nuteR/mCuXFuShp3mPQuyx4D6qq1yGcqNMfbOjYU6WfUHpVnZ9FC/41CgnjKtq8fElHNYxQzR2u0fGb960MtuT0y48=

and you would get a response like:

Key Value
— — — — -
ciphertext vault:v1:2QcEVS3oeNvhwNq36nuteR/mCuXFuShp3mPQuyx4D6qq1yGcqNMfbOjYU6WfUHpVnZ9FC/41CgnjKtq8fElHNYxQzR2u0fGb960MtuT0y48=

option #2. API

use http instead of https, and at plaintext, check that you have the correct base64 hash of what you try to encrypt.

you can also use the Web UI for this

4. Decrypt Data

in order to decrypt it all you need to do is 2 things.

first replace the word “encrypt” with “decrypt” from the command line or the API

then you would pass the ciphertext value

ex:

command line:

vault write transit/decrypt/transactions ciphertext=vault:v1:76/eOxUnnf2QfqSX6DrP1H70T7pFtarwS6vCw8/cifLdi5bA7OdvM3A6pezh0Z5QEO8sLkeudIIOhImoMINQztgavRr5yOcRG9xKv+iHItw=
Key Value
--- -----
plaintext Sm9uLFNub3csNDExMSAxMTExIDExMTEgMTExMSxyZXN0YXVyYW50LCwxODkyMDMwOTAzCg==

or as API

vault curl --header "X-Vault-Token: $VAULT_ROOT_TOKEN" \                                                                   
--request POST \
--data '{"ciphertext": "vault:v1:76/eOxUnnf2QfqSX6DrP1H70T7pFtarwS6vCw8/cifLdi5bA7OdvM3A6pezh0Z5QEO8sLkeudIIOhImoMINQztgavRr5yOcRG9xKv+iHItw="}' \
http://127.0.0.1:8200/v1/transit/decrypt/transactions | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 381 100 246 100 135 82000 45000 --:--:-- --:--:-- --:--:-- 124k
{
"request_id": "cc131dad-45ad-a7cf-90e5-bc3580220511",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": {
"plaintext": "Sm9uLFNub3csNDExMSAxMTExIDExMTEgMTExMSxyZXN0YXVyYW50LCwxODkyMDMwOTAzCg=="
},
"wrap_info": null,
"warnings": null,
"auth": null
}

Congratulate yourself once again, you completed this tutorial!

If you want to rotate they key you can continue from this tutorial

Other things:

maximum request size of 32MB that can be tuned in the listener block.

If you have more than 32MB of payload data, you can consider getting the a datakey https://learn.hashicorp.com/vault/encryption-as-a-service/eaas-transit#step-6-generate-data-key

and doing the encryption locally

If you liked this tutorial please click the clap button.

--

--

Xyz Zyx
Xyz Zyx

No responses yet