Wednesday, November 11, 2020

Convergent Encryption using Transit Secrets Engine.

$ cat create_transit_secrets_payload.json
{
        "type": "aes128-gcm96",
        "convergent_encryption": true,
        "derived": true,
        "exportable": true,
        "allow_plaintext_backup": true
}

 

$ vault write transit/keys/orders @create_transit_secrets_payload.json
Success! Data written to: transit/keys/orders
$



$ curl --header "X-Vault-Token: root" http://127.0.0.1:8200/v1/transit/keys/orders | jq -r
{
  "request_id": "edc0df98-95a4-463a-e6eb-25ad4cadebc8",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "allow_plaintext_backup": true,
    "convergent_encryption": true,
    "convergent_encryption_version": -1,
    "deletion_allowed": false,
    "derived": true,
    "exportable": true,
    "kdf": "hkdf_sha256",
    "keys": {
      "1": 1605112467
    },
    "latest_version": 1,
    "min_available_version": 0,
    "min_decryption_version": 1,
    "min_encryption_version": 0,
    "name": "orders",
    "supports_decryption": true,
    "supports_derivation": true,
    "supports_encryption": true,
    "supports_signing": false,
    "type": "aes256-gcm96"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}


$ curl --header "X-Vault-Token: root" --request LIST http://127.0.0.1:8200/v1/transit/keys | jq -r{
  "request_id": "2cc35698-5da9-6f02-ea11-13682e04346b",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "keys": [
      "orders"
    ]
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

# -- create another key name called payments.
$ curl --header "X-Vault-Token: root" --request POST --data @create-named-key-payload.json http://127.0.0.1:8200/v1/transit/keys/payments


$ curl --header "X-Vault-Token: root" --request LIST http://127.0.0.1:8200/v1/transit/keys | jq -r
{
  "request_id": "a85727cb-0f91-9d42-3e12-1e6d78261b1f",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "keys": [
      "orders",
      "payments"
    ]
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}


$ curl --header "X-Vault-Token: root" --request DELETE http://127.0.0.1:8200/v1/transit/keys/payments | jq -r

{
  "errors": [
    "error deleting policy payments: deletion is not allowed for this key"
  ]
}


$ curl --header "X-Vault-Token: root" http://127.0.0.1:8200/v1/transit/export/encryption-key/orders | jq -r
{
  "request_id": "90038666-54e9-c805-0490-1e04197cdb39",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "keys": {
      "1": "g1ldyMgMewn655RpWUjV7rbbfLu6ZXAMc0efU2r7k6Y="
    },
    "name": "orders",
    "type": "aes256-gcm96"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}


$ curl --header "X-Vault-Token: root" http://127.0.0.1:8200/v1/transit/export/encryption-key/orders/1 | jq -r
{
  "request_id": "8be6c9e3-1f55-3684-d02b-5a739791c540",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "keys": {
      "1": "g1ldyMgMewn655RpWUjV7rbbfLu6ZXAMc0efU2r7k6Y="
    },
    "name": "orders",
    "type": "aes256-gcm96"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}


$ curl --header "X-Vault-Token: root" http://127.0.0.1:8200/v1/transit/export/encryption-key/orders/2 | jq -r
{
  "errors": [
    "version does not exist or cannot be found"
  ]
}

# -- rotate the key, want to see two keys for orders.
$ curl --header "X-Vault-Token: root" --request POST http://127.0.0.1:8200/v1/transit/keys/orders/rotate | jq -r
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
 

 

$ curl --header "X-Vault-Token: root" http://127.0.0.1:8200/v1/transit/export/encryption-key/orders | jq -r
{
  "request_id": "56b149c9-7ab0-5482-0e0e-73662a389c41",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "keys": {
      "1": "g1ldyMgMewn655RpWUjV7rbbfLu6ZXAMc0efU2r7k6Y=",
      "2": "7nd4jACin+ji0SJ2qTPcd8KovmI3FsFgxVi1+RK+f2k="
    },
    "name": "orders",
    "type": "aes256-gcm96"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}
 

 

$ curl --header "X-Vault-Token: root" http://127.0.0.1:8200/v1/transit/export/encryption-key/orders/2 | jq -r
{
  "request_id": "97ed6070-c693-fd04-6395-2746b6ed2013",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "keys": {
      "2": "7nd4jACin+ji0SJ2qTPcd8KovmI3FsFgxVi1+RK+f2k="
    },
    "name": "orders",
    "type": "aes256-gcm96"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}
$

## -- fetch the keys

$ curl     --header "X-Vault-Token: root"     http://127.0.0.1:8200/v1/transit/export/encryption-key/orders | jq -r '.data.keys'

{
  "1": "GYPfzE+HTBxa5YCvVsr3jQ==",
  "2": "AErMLLRvnne0MGi1joTmGA=="
}

 

## -- below we will encrypt the text, have to pass a context parameter for convergent encryption. You will see the encrypted string is the same for every transaction.

$ vault write -format=json transit/encrypt/orders plaintext=$(base64 <<< "credit-card-number") context=$(base64 <<< "cc-field")      | jq -r ".data.ciphertext" > cipher.txt
$ cat cipher.txt
vault:v2:KDdEwZcgYbLfHfJ101pT5nozygwlrvhfSy+mvsZWEkX3RcEO9OnXI4mDxEbxPjs=
 

$ vault write -format=json transit/encrypt/orders plaintext=$(base64 <<< "credit-card-number") context=$(base64 <<< "cc-field")      | jq -r ".data.ciphertext" > cipher.txt.1
$ cat cipher.txt.1vault:v2:KDdEwZcgYbLfHfJ101pT5nozygwlrvhfSy+mvsZWEkX3RcEO9OnXI4mDxEbxPjs=
$


$ vault write -format=json transit/encrypt/orders plaintext=$(base64 <<< "credit-card-number") context=$(base64 <<< "cc-field-2")      | jq -r ".data.ciphertext" > cipher.txt.2
$ cat cipher.txt.2
vault:v2:4PgP9YEqB23kR4UpzRbq/M7k6fWTZwXzFH9xcopSdejM5JeVByXoUmbgxJpaiWA=
$


## -- Decrypt

$ vault write -format=json transit/decrypt/orders ciphertext=$(cat cipher.txt) context=$(base64 <<< "cc-field") | jq -r ".data.plaintext"
Y3JlZGl0LWNhcmQtbnVtYmVyCg==
 

$ base64 -d <<< Y3JlZGl0LWNhcmQtbnVtYmVyCg==
credit-card-number
$

$ vault write -format=json transit/decrypt/orders ciphertext=$(cat cipher.txt.1) context=$(base64 <<< "cc-field") | jq -r ".data.plaintext"
Y3JlZGl0LWNhcmQtbnVtYmVyCg==
 

## -- what happens if wrong context is sent.. it fails

$ vault write -format=json transit/decrypt/orders ciphertext=$(cat cipher.txt.2) context=$(base64 <<< "cc-field") | jq -r ".data.plaintext"
Error writing data to transit/decrypt/orders: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/transit/decrypt/orders
Code: 400. Errors:

* invalid ciphertext: unable to decrypt
$


## -- export or backup the key

$ vault read transit/backup/orders -format=json
{
  "request_id": "49cf6800-8488-a925-b897-8800b9e5410c",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "backup": "eyJwb2xpY3kiOnsibmFtZSI6Im9yZGVycyIsImtleXMiOnsiMSI6eyJrZXkiOiJHWVBmekUrSFRCeGE1WUN2VnNyM2pRPT0iLCJobWFjX2tleSI6IkI3andqdWpkMXdxRiswK3h5MVRWbUpLYUdQTUR5c0pyQkRYK00weFIveU09IiwidGltZSI6IjIwMjAtMTEtMTFUMTg6MjM6MDcuMTAwMzA4NTY3WiIsImVjX3giOm51bGwsImVjX3kiOm51bGwsImVjX2QiOm51bGwsInJzYV9rZXkiOm51bGwsInB1YmxpY19rZXkiOiIiLCJjb252ZXJnZW50X3ZlcnNpb24iOjMsImNyZWF0aW9uX3RpbWUiOjE2MDUxMTg5ODd9LCIyIjp7ImtleSI6IkFFck1MTFJ2bm5lME1HaTFqb1RtR0E9PSIsImhtYWNfa2V5IjoiWjFBYTZ3VktBaUVFZmFjQ2YwVEZkc1czUTZsckFIaDRwVThaMm1yMFNKMD0iLCJ0aW1lIjoiMjAyMC0xMS0xMVQxODozMTozMy4xNjY3MjMwNDhaIiwiZWNfeCI6bnVsbCwiZWNfeSI6bnVsbCwiZWNfZCI6bnVsbCwicnNhX2tleSI6bnVsbCwicHVibGljX2tleSI6IiIsImNvbnZlcmdlbnRfdmVyc2lvbiI6MywiY3JlYXRpb25fdGltZSI6MTYwNTExOTQ5M319LCJkZXJpdmVkIjp0cnVlLCJrZGYiOjEsImNvbnZlcmdlbnRfZW5jcnlwdGlvbiI6dHJ1ZSwiZXhwb3J0YWJsZSI6dHJ1ZSwibWluX2RlY3J5cHRpb25fdmVyc2lvbiI6MSwibWluX2VuY3J5cHRpb25fdmVyc2lvbiI6MCwibGF0ZXN0X3ZlcnNpb24iOjIsImFyY2hpdmVfdmVyc2lvbiI6MiwiYXJjaGl2ZV9taW5fdmVyc2lvbiI6MCwibWluX2F2YWlsYWJsZV92ZXJzaW9uIjowLCJkZWxldGlvbl9hbGxvd2VkIjpmYWxzZSwiY29udmVyZ2VudF92ZXJzaW9uIjotMSwidHlwZSI6OCwiYmFja3VwX2luZm8iOnsidGltZSI6IjIwMjAtMTEtMTFUMTg6NTQ6MDIuODA4MzU5Njc5WiIsInZlcnNpb24iOjJ9LCJyZXN0b3JlX2luZm8iOm51bGwsImFsbG93X3BsYWludGV4dF9iYWNrdXAiOnRydWUsInZlcnNpb25fdGVtcGxhdGUiOiIiLCJzdG9yYWdlX3ByZWZpeCI6IiJ9LCJhcmNoaXZlZF9rZXlzIjp7ImtleXMiOlt7ImtleSI6bnVsbCwiaG1hY19rZXkiOm51bGwsInRpbWUiOiIwMDAxLTAxLTAxVDAwOjAwOjAwWiIsImVjX3giOm51bGwsImVjX3kiOm51bGwsImVjX2QiOm51bGwsInJzYV9rZXkiOm51bGwsInB1YmxpY19rZXkiOiIiLCJjb252ZXJnZW50X3ZlcnNpb24iOjAsImNyZWF0aW9uX3RpbWUiOjB9LHsia2V5IjoiR1lQZnpFK0hUQnhhNVlDdlZzcjNqUT09IiwiaG1hY19rZXkiOiJCN2p3anVqZDF3cUYrMCt4eTFUVm1KS2FHUE1EeXNKckJEWCtNMHhSL3lNPSIsInRpbWUiOiIyMDIwLTExLTExVDE4OjIzOjA3LjEwMDMwODU2N1oiLCJlY194IjpudWxsLCJlY195IjpudWxsLCJlY19kIjpudWxsLCJyc2Ffa2V5IjpudWxsLCJwdWJsaWNfa2V5IjoiIiwiY29udmVyZ2VudF92ZXJzaW9uIjozLCJjcmVhdGlvbl90aW1lIjoxNjA1MTE4OTg3fSx7ImtleSI6IkFFck1MTFJ2bm5lME1HaTFqb1RtR0E9PSIsImhtYWNfa2V5IjoiWjFBYTZ3VktBaUVFZmFjQ2YwVEZkc1czUTZsckFIaDRwVThaMm1yMFNKMD0iLCJ0aW1lIjoiMjAyMC0xMS0xMVQxODozMTozMy4xNjY3MjMwNDhaIiwiZWNfeCI6bnVsbCwiZWNfeSI6bnVsbCwiZWNfZCI6bnVsbCwicnNhX2tleSI6bnVsbCwicHVibGljX2tleSI6IiIsImNvbnZlcmdlbnRfdmVyc2lvbiI6MywiY3JlYXRpb25fdGltZSI6MTYwNTExOTQ5M31dfX0K"
  },
  "warnings": null
}