Method: Generate Data Key

Description

This endpoint generates a new random key and the value of the new key is wrapped (encrypted) with the named key in the specified vault. Optionally return the plaintext of the key as well. Whether plaintext is returned depends on the type used (wrapped vs plaintext) and the users permission in the vault.

Note

This endpoint requires at least Read permission in the affected vault.

Note

Returning the plaintext requires Write permission in the affected vault.

See the overview of how transparent encryption in StoredSafe can help solve key distribution problems.

URL Syntax

/api/{version}/transparent/:vaultid/datakey/:type/:name

HTTP Method

POST

Successful HTTP Response

200

Parameters

Parameter name Description Parameter type Type Default Mandatory Comment
X-Http-Token StoredSafe token HTTP Header String   1) Preferred method
token StoredSafe token JSON-encoded String   1) Legacy method
vaultid Vault-ID URL-encoded String   Yes  
type Wrapped or plaintext URL-encoded String plaintext Yes wrapped, plaintext (plaintext requires Write permission in the vault)
name Key name URL-encoded String   Yes  
key_version Key version JSON-encoded String     Will use Latest version if unspecified
bits Key size JSON-encoded Integer 256   128, 256 or 512

Note

1) One of the methods is required.

Response Attributes

Attribute Description Type
CALLINFO.errorcodes Number of errors Integer
CALLINFO.errors Number of errors Integer
CALLINFO.general Information Array
CALLINFO.handler Handler used String
CALLINFO.status SUCCESS or FAIL String
CALLINFO.token Rotated StoredSafe token 1) String
CALLINFO.key_version Latest key version String
CALLINFO.ciphertext Ciphertext (Base64 encoded) String
CALLINFO.plaintext Plaintext (Base64 encoded) String
CALLINFO.objectid Object-ID String
DATA Supplied data in prior API-call String
HEADERS.(headers) HTTP Headers String
PARAMS Route parameters (empty) Array
ERRORCODES Error code and text 2) Object
ERRORS Error code and text 2) Array

Note

1) Token to be used in subsequent calls
2) Only present if errors

Examples

Obtain a randomized datakey using high entropy in both plaintext and chipertext, wrapped using the latest version (v2) of the key my-new-key in the vault (vaultid) 179.

Request

POST /api/1.0/transparent/179/datakey/plaintext/my-new-key
x-http-token: your_storedsafe_token

Response

HTTP/2 200
Content-type: application/json; charset=UTF-8
{
    "CALLINFO": {
        "errorcodes": 0,
        "errors": 0,
        "general": [],
        "handler": "EncryptionHandler",
        "status": "SUCCESS",
        "token": "rotated_storedsafe_token",
        "name": "my-new-key",
        "ciphertext": "storedsafe:v2:rsUKcXUaeUqIlAihBB7c5NoX9xAUxcJt8L1xS1bDuIulobKIp1OAOQ==",
        "plaintext": "Z0VNRHZRcUIwVmhhNE5UZjdZSlU5Y091QTFlZTZRbVNEVTRJNnFVWQo="
    },
    "DATA": {
        "name": "my-new-key",
        "vaultid": "179",
        "token": "your_storedsafe_token"
    },
    "HEADERS": {
        "Accept": "*/*",
        "Content-Length": "169",
        "Content-Type": "application/json",
        "Host": "safe.domain.cc",
        "User-Agent": "curl/7.64.1",
        "X-Http-Token": "your_storedsafe_token"
    },
    "PARAMS": []
}

Annotated example

In this example, we will show how to encrypt a local file (/data/large_file.blob) using AES256-GCM and using StoredSafe to maintain and secure the key for the symmetric encryption.

  1. Start by generating a datakey using the /datakey endpoint, requesting both a wrapped key and a copy in cleartext (/plaintext/).

The ciphertext returned is wrapped (encrypted) with the named key my-new-key, as specified in the REST call.

$ curl --header "x-http-token: ..." --request GET https://safe.domain.cc/api/1.0/transparent/179/datakey/plaintext/my-new-key
.
.
Content-type: application/json; charset=UTF-8
{
    "CALLINFO": {
        "ciphertext": "storedsafe:v2:rsUKcXUaeUqIlAihBB7c5NoX9xAUxcJt8L1xS1bDuIulobKIp1OAOQ==",
        "plaintext": "Z0VNRHZRcUIwVmhhNE5UZjdZSlU5Y091QTFlZTZRbVNEVTRJNnFVWQo="
  1. Next step is to base64 decode the plaintext key and save it to a file.
$ base64 -d <<<Z0VNRHZRcUIwVmhhNE5UZjdZSlU5Y091QTFlZTZRbVNEVTRJNnFVWQo= >/data/key.bin
  1. And then use the plaintext key to encrypt a local file, after creating (and saving) a random 12-byte IV to a file.
$ dd if=/dev/random bs=12 count=1 >/data/iv.file
$ aesgcm enc -iv /data/iv.file -tag /data/tag.file -in /data/large_file.blob -out /data/large_file.blob.enc -key /data/key.bin
  1. Finally, save the wrapped encryption key.

Since it wrapped (e.g. encrypted by another key), it can safely be stored together with the encrypted file.

$ echo "storedsafe:v2:rsUKcXUaeUqIlAihBB7c5NoX9xAUxcJt8L1xS1bDuIulobKIp1OAOQ==" > /data/key.wrapped
  1. Securely delete the plaintext key.
$ sterialize --passes 20 /data/key.bin

Note

Now several days, weeks, months or years can pass. Members in vault 179 might have shifted over time, but as long as the current user has at least read permission in the vault at the time of decryption, decryption will work.

  1. When the file needs to be decrypted, use the decrypt endpoint to unwrap the wrapped key.
$ curl --header "x-http-token: ..." --request POST --data '{ "ciphertext": "storedsafe:v2:rsUKcXUaeUqIlAihBB7c5NoX9xAUxcJt8L1xS1bDuIulobKIp1OAOQ==" }' https://safe.domain.cc/api/1.0/transparent/decrypt/my-new-key
.
.
Content-type: application/json; charset=UTF-8
{
    "CALLINFO": {
        "plaintext": "Z0VNRHZRcUIwVmhhNE5UZjdZSlU5Y091QTFlZTZRbVNEVTRJNnFVWQo="
$ base64 -d <<<Z0VNRHZRcUIwVmhhNE5UZjdZSlU5Y091QTFlZTZRbVNEVTRJNnFVWQo= >key.bin
  1. And finally, use the unwrapped key to decrypt the locally stored data.
$ aesgcm dec -iv /data/iv.file -tag /data/tag.file -in /data/large_file.blob.enc -out /data/large_file.blob -key /data/key.bin