{
"cells": [
{
"cell_type": "markdown",
"id": "76e95abf-de0c-4559-b9fd-9d983c62ea0b",
"metadata": {},
"source": [
"# Server Key Management"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "5cf3ddbe-149e-4e5e-ac79-52092770b5e5",
"metadata": {},
"outputs": [],
"source": [
"%load_ext sql"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "c516e4bc-4622-43ef-8183-9b9607b69bd0",
"metadata": {},
"outputs": [],
"source": [
"%config SqlMagic.feedback=False\n",
"%config SqlMagic.displaycon=False\n",
"%sql postgresql://postgres@/"
]
},
{
"cell_type": "markdown",
"id": "bf0842f4-6cbd-4fe5-bf19-2ba45db59548",
"metadata": {},
"source": [
"The core feature of pgsodium its its ability to manage encryption keys for you, you so that you never reference a raw encryption key, but instead you reference keys *by ID*. A key id is a UUID that uniquely identifies the key used. An example of using Server Key Management can be found in the section on [Transparent Column Encryption](Transparent_Column_Encryption.md) and is most of the API examples that can take key UUIDs are arguments.\n",
"\n",
"## The hidden root key\n",
"\n",
" \n",
"\n",
"## Create a new Key\n",
"\n",
"pgsodium can manage two types of keys, *derived* keys, and *external* keys. Derived keys use libsodium to \n",
"\n",
"Server managed keys are created with the `pgsodium.create_key()` function. This function takes a few optional parameters:\n",
"- `key_type`: The type of key to create, the default is `aead-det`. Can be one of:\n",
" - `aead-det`\n",
" - `aead-ietf`\n",
" - `hmacsha512`\n",
" - `hmacsha256`\n",
" - `auth`\n",
" - `secretbox`\n",
" - `secretstream`\n",
" - `shorthash`\n",
" - `generichash`\n",
" - `kdf`\n",
"- `name`: An optional *unique* name for the key. The default is NULL which makes an \"anonymous\" key.\n",
"- `derived_key`: An optional raw external key, for example an hmac key from an external service. pgsodium will store this key encrypted with TCE.\n",
"- `derived_key_nonce`: An optional nonce for the raw key, if none is provided a new random `aead-det` nonce will be generated using `pgsodium.crypto_aead_det_noncegen()`.\n",
"- `parent_key`: If `raw_key` is not null, then this key id is used to encrypt the raw key. The default is to generate a new `aead-det` key.\n",
"- `derived_context`\n",
"- `expires`\n",
"- `associated_data`\n",
"\n",
"`pgsodium.create_key()` returns a new row in the `pgsodium.valid_key` view. For most purposes, you usually just need the new key's ID to start using it. For example, here's a new external shahmac256 key being created and used to verify a payload:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "df926fda-416e-43bd-8df1-cf0fc3864642",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"b'\\x1d\\xa5\\xf2\\xa0a\\xa8\\x03 \\x9b\\x88J\\xfe\\xd2Xc\\x0cG\\xc5{\\xc3W\\xd7\\x91KXp\\x87\\x15\\x02\"\\xd6\\xf6'\n"
]
}
],
"source": [
"external_key = %sql select pgsodium.crypto_auth_hmacsha256_keygen()\n",
"external_key = bytes(external_key[0][0])\n",
"print(external_key)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "45eb7a0f-b260-4fd9-929f-1a2b9d6bc29c",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
" \n",
" id | \n",
" name | \n",
" status | \n",
" key_type | \n",
" key_id | \n",
" key_context | \n",
" created | \n",
" expires | \n",
" associated_data | \n",
"
\n",
" \n",
" 92e24493-2df6-422b-8c75-00c82b1097c4 | \n",
" None | \n",
" valid | \n",
" hmacsha256 | \n",
" None | \n",
" None | \n",
" 2022-09-05 19:46:07.340760+00:00 | \n",
" None | \n",
" | \n",
"
\n",
"
"
],
"text/plain": [
"[(UUID('92e24493-2df6-422b-8c75-00c82b1097c4'), None, 'valid', 'hmacsha256', None, None, datetime.datetime(2022, 9, 5, 19, 46, 7, 340760, tzinfo=datetime.timezone.utc), None, '')]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql select * from pgsodium.create_key('hmacsha256', raw_key:=:external_key)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "aa4e304f-69cc-42f8-9335-9d022fc90b17",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" id | \n",
" key_type | \n",
" parent_key | \n",
" length | \n",
"
\n",
" \n",
" 5a8720af-50aa-4bd9-a9f1-c71065e75a88 | \n",
" hmacsha256 | \n",
" 451843b3-74f8-4458-bc2d-5a88c6024832 | \n",
" 32 | \n",
"
\n",
" \n",
" 9fac7ff7-10d7-4139-966b-f7317e4486b2 | \n",
" hmacsha256 | \n",
" a1f91b67-2793-4788-ab8e-4fca32e360da | \n",
" 32 | \n",
"
\n",
" \n",
" 92e24493-2df6-422b-8c75-00c82b1097c4 | \n",
" hmacsha256 | \n",
" cc815230-06c6-4d57-9780-ac2a2dc026bc | \n",
" 32 | \n",
"
\n",
"
"
],
"text/plain": [
"[(UUID('5a8720af-50aa-4bd9-a9f1-c71065e75a88'), 'hmacsha256', UUID('451843b3-74f8-4458-bc2d-5a88c6024832'), 32),\n",
" (UUID('9fac7ff7-10d7-4139-966b-f7317e4486b2'), 'hmacsha256', UUID('a1f91b67-2793-4788-ab8e-4fca32e360da'), 32),\n",
" (UUID('92e24493-2df6-422b-8c75-00c82b1097c4'), 'hmacsha256', UUID('cc815230-06c6-4d57-9780-ac2a2dc026bc'), 32)]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%sql select id, key_type, parent_key, length(decrypted_raw_key) from pgsodium.decrypted_key where key_type = 'hmacsha256';"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}