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