|
| 1 | +--- |
| 2 | +meta: |
| 3 | + title: Encrypting and decrypting data with a Key Manager data encryption key |
| 4 | + description: Learn how to use Tink with Scaleway's Key Manager to securely encrypt and manage keys, including KEKs and DEKs, in Go applications. |
| 5 | +content: |
| 6 | + h1: Encrypting and decrypting data with a Key Manager data encryption key |
| 7 | + paragraph: Learn how to use Tink with Scaleway's Key Manager to securely encrypt and manage keys, including KEKs and DEKs, in Go applications. |
| 8 | +tags: key-manager encryption decryption kms dek data-encryption-key |
| 9 | +dates: |
| 10 | + validation: 2025-01-06 |
| 11 | + posted: 2025-01-06 |
| 12 | +categories: |
| 13 | + - identity-and-access-management |
| 14 | +--- |
| 15 | + |
| 16 | +This page shows you how to encrypt and decrypt data using your Key Manager [data encryption key](/identity-and-access-management/key-manager/concepts/#data-encryption-key-dek) and [Tink](https://github.com/tink-crypto/tink/tree/master). |
| 17 | + |
| 18 | +<Macro id="requirements" /> |
| 19 | + |
| 20 | +- A Scaleway account logged into the [console](https://console.scaleway.com) |
| 21 | +- [Owner](/identity-and-access-management/iam/concepts/#owner) status or [IAM permissions](/identity-and-access-management/iam/concepts/#permission) allowing you to perform actions in the intended Organization |
| 22 | +- Created a key encryption key either from the [Scaleway console](/identity-and-access-management/key-manager/how-to/create-km-key/) or the [Key Manager API](https://www.scaleway.com/en/developers/api/key-manager/#path-keys-create-a-key) |
| 23 | +- Retrieved your key encryption key's ID |
| 24 | +- A valid [API key](/identity-and-access-management/iam/how-to/create-api-keys/) |
| 25 | +- Downloaded and configured the [Scaleway CLI](https://github.com/scaleway/scaleway-cli?tab=readme-ov-file#getting-started) |
| 26 | +- [Dowloaded Python](https://www.python.org/downloads/) or [Go](https://go.dev/doc/install) |
| 27 | +- [Created a Key Manager data encryption key](/identity-and-access-management/key-manager/how-to/create-manage-dek/) |
| 28 | + |
| 29 | +## Encrypt and decrypt data with Tink and Key Manager |
| 30 | + |
| 31 | +The [Scaleway Tink extension](https://gitlab.infra.online.net/secret-manager/tink-go-scwkms) generates a unique data encryption key for each piece of data that it encrypts. This method follows the cryptography best practices of using unique data encryption keys for each encryption operation. |
| 32 | + |
| 33 | +Tink is an open source cryptography library written by cryptographers and security engineers at Google. |
| 34 | + |
| 35 | +In order to use Tink for data encryption, you need to provide it with a key URI and a configuration file: |
| 36 | + |
| 37 | +- The key URI points to your key encryption key (KEK) in Scaleway Key Manager. |
| 38 | + |
| 39 | +- The configuration file grants Tink the necessary permissions to access and use the KEK identified by the Key URI. |
| 40 | + |
| 41 | +Tink generates a data encryption key (DEK) which will be used to encrypt your data. The DEK itself is then encrypted using the KEK from Key Manager. This ensures that the DEK is securely protected and can only be decrypted by someone with access to the KEK. |
| 42 | + |
| 43 | +The final output is a single ciphertext that includes both the encrypted data and the encrypted DEK (wrapped DEK). This means that the DEK and the data are both securely packaged together. |
| 44 | + |
| 45 | +Scaleway supports the **Python and Go Tink providers**. |
| 46 | + |
| 47 | +### Configuring your environment variables |
| 48 | + |
| 49 | +Open a terminal and paste the following command to export your environment variables. Make sure that you replace the placeholder values with your own. |
| 50 | + |
| 51 | +```bash |
| 52 | + |
| 53 | + export SCW_ACCESS_KEY="<access-key>" |
| 54 | + export SCW_SECRET_KEY="<secret-key>" |
| 55 | + export SCW_DEFAULT_ORGANIZATION_ID="<organization-id>" |
| 56 | + export SCW_PROJECT_ID="<project-id>" |
| 57 | + export SCW_DEFAULT_REGION="<region>" |
| 58 | + export SCW_API_URL="<api-url>" |
| 59 | + export SCW_KMS_KEY_ID="<key-id>" |
| 60 | +``` |
| 61 | + |
| 62 | +### Using the Python Tink provider |
| 63 | + |
| 64 | +1. Open a terminal and install [Poetry](https://python-poetry.org/): |
| 65 | + |
| 66 | + ```bash |
| 67 | + curl -sSL https://install.python-poetry.org | python3 - |
| 68 | + ``` |
| 69 | + <Message type="note"> |
| 70 | + Poetry is used to manage dependencies. You can however use any package management tool of your choice. For more information on managing dependencies, refer to the [official Python documentation](https://packaging.python.org/en/latest/tutorials/managing-dependencies/). |
| 71 | + </Message> |
| 72 | + |
| 73 | +2. Add the [Scaleway Tink provider for Python](https://github.com/scaleway/tink-py-scwkms/tree/v0.1.0): |
| 74 | + ```bash |
| 75 | + poetry add scaleway-tink |
| 76 | + ``` |
| 77 | +3. Copy the following template: |
| 78 | + ```bash |
| 79 | + from scaleway_tink.integration.scwkms import clientimport base64 |
| 80 | + import base64 |
| 81 | + import os |
| 82 | + |
| 83 | + def main(): |
| 84 | + key_uri = f"scw-kms://{os.getenv('SCW_KMS_KEY_ID')}" |
| 85 | + aead = client.ScwKmsClient(None, None).get_aead(key_uri) |
| 86 | + |
| 87 | + plaintext = b'message' |
| 88 | + ciphertext = aead.encrypt(plaintext, b'') |
| 89 | + |
| 90 | + print(f"plaintext: {plaintext.decode()}") |
| 91 | + print(f"ciphertext in base64: {base64.b64encode(ciphertext).decode()}") |
| 92 | + print(f"decrypt(ciphertext): {aead.decrypt(ciphertext, b'').decode()}") |
| 93 | + |
| 94 | + main() |
| 95 | + ``` |
| 96 | +4. Create a file named `example.py` and paste the code from the step above in it. |
| 97 | + |
| 98 | +5. Run your code: |
| 99 | + ```bash |
| 100 | + python3 ./example.py |
| 101 | + ``` |
| 102 | + |
| 103 | + |
| 104 | +### Using the Go Tink provider |
| 105 | + |
| 106 | +1. Open a terminal and add the [Scaleway Tink provider for Go](https://github.com/scaleway/tink-go-scwkms/tree/main) to your `go.mod` file. |
| 107 | + |
| 108 | + ```bash |
| 109 | + go get github.com/scaleway/tink-go-scwkms |
| 110 | + ``` |
| 111 | + |
| 112 | +2. Add the Tink library for Go to your `go.mod` file: |
| 113 | + ```bash |
| 114 | + go get github.com/tink-crypto/tink-go/v2 |
| 115 | + go mod tidy |
| 116 | + ``` |
| 117 | + <Message type="note"> |
| 118 | + The Tink library for Go is a cryptographic library that simplifies encryption, decryption, and key management operations. |
| 119 | + </Message> |
| 120 | +3. Create a Go project with a `test.go` file in it. |
| 121 | +4. Copy the following code. |
| 122 | + ```bash |
| 123 | + package main |
| 124 | + |
| 125 | + import ( |
| 126 | + "fmt" |
| 127 | + "github.com/scaleway/tink-go-scwkms/integration/scwkms" |
| 128 | + "github.com/tink-crypto/tink-go/v2/aead" |
| 129 | + "log" |
| 130 | + "os" |
| 131 | + ) |
| 132 | + |
| 133 | + func main() { |
| 134 | + const keyURIPrefix = "scw-kms://regions/<region>/keys/" |
| 135 | + keyURI := keyURIPrefix + os.Getenv("SCW_KMS_KEY_ID") |
| 136 | + |
| 137 | + client, err := scwkms.NewClient(keyURIPrefix) |
| 138 | + if err != nil { |
| 139 | + log.Fatal(err) |
| 140 | + } |
| 141 | + |
| 142 | + kekAEAD, err := client.GetAEAD(keyURI) |
| 143 | + if err != nil { |
| 144 | + log.Fatal(err) |
| 145 | + } |
| 146 | + |
| 147 | + // Get the KMS envelope AEAD primitive. |
| 148 | + dekTemplate := aead.AES256GCMKeyTemplate() |
| 149 | + primitive := aead.NewKMSEnvelopeAEAD2(dekTemplate, kekAEAD) |
| 150 | + if err != nil { |
| 151 | + log.Fatal(err) |
| 152 | + } |
| 153 | + |
| 154 | + // Use the primitive. |
| 155 | + plaintext := []byte("message") |
| 156 | + associatedData := []byte("example KMS envelope AEAD encryption") |
| 157 | + |
| 158 | + ciphertext, err := primitive.Encrypt(plaintext, associatedData) |
| 159 | + if err != nil { |
| 160 | + log.Fatal(err) |
| 161 | + } |
| 162 | + |
| 163 | + fmt.Printf("Plaintext: %s\n", plaintext) |
| 164 | + fmt.Printf("Ciphertext (base64): %s\n", ciphertext) |
| 165 | + |
| 166 | + decryptedCiphertext, err := primitive.Decrypt(ciphertext, associatedData) |
| 167 | + if err != nil { |
| 168 | + log.Fatal(err) |
| 169 | + } |
| 170 | + |
| 171 | + fmt.Printf("Decrypted ciphertext: %s\n", decryptedCiphertext) |
| 172 | + } |
| 173 | + ``` |
| 174 | +5. Paste the code from the step above in your `test.go` file. |
| 175 | +6. Replace `<region>` with the region where your key is located and save your changes. |
| 176 | +7. Run your code: |
| 177 | + ```bash |
| 178 | + go run test.go |
| 179 | + ``` |
| 180 | +
|
| 181 | +<br> |
| 182 | +
|
| 183 | +## Manually encrypt and decrypt data with a Key Manager DEK |
| 184 | +
|
| 185 | +### OpenSSL overview |
| 186 | +
|
| 187 | +OpenSSL is a software library for secure communication over computer networks. It is widely used for cryptographic functions. |
| 188 | +
|
| 189 | +To decrypt or encrypt your data using OpenSSL, you need to send your encrypted DEK to Key Manager using the [Decrypt data operation](https://www.scaleway.com/en/developers/api/key-manager/#path-keys-decrypt-data). |
| 190 | +
|
| 191 | +Scaleway Key Manager then uses your key encryption key (KEK) to decrypt the encrypted DEK, returning it to its plaintext (unencrypted) form, which you can then use to decrypt your actual data. |
| 192 | +
|
| 193 | +<Message type="important"> |
| 194 | + - **It is not recommended to you use OpenSSL in a production environment**. |
| 195 | + - You should **never save the plaintext DEK on disk or any permanent storage, as it poses a security risk**. |
| 196 | +</Message> |
| 197 | +
|
| 198 | +
|
| 199 | +### Encrypting data with OpenSSL |
| 200 | +
|
| 201 | +
|
| 202 | +To encrypt your data using OpenSSl, we need to: |
| 203 | +
|
| 204 | +1. Decrypt your encrypted DEK using your Key Manager key (key encryption key) |
| 205 | +
|
| 206 | +2. Create a `plaintext.txt` file in which we will paste your plaintext data. |
| 207 | +
|
| 208 | +3. Encrypt the content of `plaintext.txt` using OpenSSL and the AES-256-CBC cipher encryption algorithm. |
| 209 | +
|
| 210 | +Open a terminal and paste the following command to perform the actions described above. Make sure that you replace `<kek_id>` and `<my_encrypted_data_key>` with the relevant values. |
| 211 | +```bash |
| 212 | +# Decrypt the encrypted DEK using scw key decrypt |
| 213 | +decrypted_data_key=$(scw keymanager key decrypt key-id=<kek_id> ciphertext=<my_encrypted_data_key> | awk '$1 == "Plaintext" {print $2}' | base64 -d) |
| 214 | +
|
| 215 | +# Put your data plaintext into a .txt file |
| 216 | +echo -n "Your plaintext here" > plaintext.txt |
| 217 | +
|
| 218 | +# Encrypt your file using OpenSSL and AES-256-CBC |
| 219 | +openssl enc -aes-256-cbc -in plaintext.txt -out encrypted.bin -K $(echo -n "$decrypted_data_key" | hexdump -ve '/1 "%02x"') -iv 0 -nosalt -p |
| 220 | +
|
| 221 | +# Remove the plaintext data |
| 222 | +rm plaintext.txt |
| 223 | +``` |
| 224 | +
|
| 225 | +### Decrypting data with OpenSSL |
| 226 | +
|
| 227 | +To decrypt your encrypted data using OpenSSL, we need to: |
| 228 | +
|
| 229 | +1. Decrypt your encrypted DEK using your Key Manager key (key encryption key) |
| 230 | +
|
| 231 | +2. Decrypt the content of `encrypted.bin` which contains your encrypted data, using OpenSSL and the AES-256-CBC cipher encryption algorithm. |
| 232 | +
|
| 233 | +Open a terminal and paste the following command to perform the actions described above. Make sure that you replace `<kek_id>` and `<my_encrypted_data_key>` with the relevant values. |
| 234 | +```bash |
| 235 | + # Decrypt the encrypted DEK using scw key decrypt |
| 236 | + decrypted_data_key=$(scw keymanager key decrypt key-id=<kek_id> ciphertext=<my_encrypted_data_key> | awk '$1 == "Plaintext" {print $2}' | base64 -d) |
| 237 | +
|
| 238 | + # Decrypt your data using OpenSSL and AES-256-CBC |
| 239 | + openssl enc -aes-256-cbc -d -in encrypted.bin -out decrypted.bin -K $(echo -n "$decrypted_data_key" | hexdump -ve '/1 "%02x"') -iv 0 -nosalt -p |
| 240 | +``` |
| 241 | +
|
| 242 | +<Message type="tip"> |
| 243 | + If you do not wish to use OpenSSL to encrypt and decrypt your data encryption key, you can do it manually using the procedure below, which follows best practices. |
| 244 | +</Message> |
| 245 | +
|
| 246 | +
|
| 247 | +### Encrypting a DEK manually |
| 248 | +
|
| 249 | +1. [Generate one data encryption key](/generate-dek-cli-api/) for each plaintext you want to encrypt. |
| 250 | +
|
| 251 | + <Message type="tip"> |
| 252 | + This ensures that each encryption operation uses a unique encryption key, enhancing security. |
| 253 | + </Message> |
| 254 | +
|
| 255 | +2. Use your newly created DEK to encrypt the desired plaintext securely. |
| 256 | +
|
| 257 | + <Message type="note"> |
| 258 | + We recommend using **standard and well-established ciphers** such as `AES` (Advanced Encryption Standard), to perform the encryption operation. |
| 259 | + </Message> |
| 260 | +
|
| 261 | +3. After encrypting the plaintext using your DEK, concatenate the encrypted DEK with the resulting ciphertext. This ensures that the encrypted DEK is securely associated with the corresponding ciphertext for decryption. |
| 262 | +
|
| 263 | +### Decrypting a DEK manually |
| 264 | +
|
| 265 | +1. Extract the encrypted DEK from the ciphertext. |
| 266 | +
|
| 267 | + <Message type="note"> |
| 268 | + Extracting an encrypted DEK from the ciphertext means that we are separating the encrypted DEK from the ciphertext. |
| 269 | + </Message> |
| 270 | +
|
| 271 | +2. Decrypt the encrypted DEK using your Key manager key (key encryption key). |
| 272 | +3. Use the resulting DEK's plaintext to decrypt the ciphertext. |
| 273 | +
|
| 274 | + <Message type="note"> |
| 275 | + Use the same cryptographic algorithm and decryption mechanism as the ones you used during the encryption process. |
| 276 | + </Message> |
| 277 | +4. Delete the plaintext DEK from permanent storage after using it to enhance security. |
| 278 | +
|
| 279 | +<br> |
0 commit comments