Skip to content

Commit df5b0d8

Browse files
mmrqsMélanie Marquesnerda-codesiManubene2k1
authored
feat(key_manager): add documentation about asymmetric features (#4981)
* feat(key_manager): add documentation about creating and verify digital signatures * docs(review): menu titles * docs(review): review of en/decrypting data with asym key * Update sign-verify-key-with-go-sdk.mdx * Update encrypt-decrypt-asymmetric-key-with-go-sdk.mdx update frontmatter * Update sign-verify-key-with-go-sdk.mdx update frontmatter --------- Co-authored-by: Mélanie Marques <[email protected]> Co-authored-by: Néda <[email protected]> Co-authored-by: numa <[email protected]> Co-authored-by: Benedikt Rollik <[email protected]>
1 parent 1993296 commit df5b0d8

File tree

3 files changed

+299
-0
lines changed

3 files changed

+299
-0
lines changed

menu/navigation.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,58 @@
857857
"slug": "adding-ai-to-vscode-using-continue"
858858
},
859859
{
860+
"label": "Encrypting and decrypting data streams with Streaming AEAD, Tink and Key Manager",
861+
"slug": "encrypt-decrypt-keys-with-streaming-aead-tink"
862+
},
863+
{
864+
"label": "Encrypting and decrypting data with an asymmetric key",
865+
"slug": "encrypt-decrypt-asymmetric-key-with-go-sdk"
866+
},
867+
{
868+
"label": "Managing signatures using the Scaleway Go SDK and Key Manager",
869+
"slug": "sign-verify-key-with-go-sdk"
870+
}
871+
],
872+
"label": "API/CLI",
873+
"slug": "api-cli"
874+
}
875+
],
876+
"label": "Key Manager",
877+
"slug": "key-manager"
878+
}
879+
],
880+
"label": "Security & Identity",
881+
"category": "identity-and-access-management"
882+
},
883+
{
884+
"icon": "envFootprint",
885+
"items": [
886+
{
887+
"items": [
888+
{
889+
"label": "Overview",
890+
"slug": "../environmental-footprint"
891+
},
892+
{
893+
"label": "Concepts",
894+
"slug": "concepts"
895+
},
896+
{
897+
"label": "FAQ",
898+
"slug": "faq"
899+
},
900+
{
901+
"items": [
902+
{
903+
"label": "Track your monthly environmental footprint report",
904+
"slug": "track-monthly-footprint"
905+
}
906+
],
907+
"label": "How to",
908+
"slug": "how-to"
909+
},
910+
{
911+
"items": [
860912
"label": "Adding AI to IntelliJ IDEA using Continue",
861913
"slug": "adding-ai-to-intellij-using-continue"
862914
},
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
title: Encrypting and decrypting data with an asymmetric key
3+
description: Learn how to encrypt and decrypt data with an asymmetric key using Key Manager and the Scaleway Go SDK.
4+
tags: key sensitive-data encrypt decrypt asymmetric digest
5+
dates:
6+
validation: 2025-05-27
7+
posted: 2025-05-27
8+
---
9+
10+
Scaleway's Key Manager provides a secure way to manage asymmetric keys, allowing you to offload sensitive cryptographic operations to a managed service. This documentation page shows you how to integrate the Scaleway Go SDK to encrypt and decrypt data using an `rsa_oaep_3072_sha256` key directly through the [Key Manager API](https://www.scaleway.com/en/developers/api/key-manager/).
11+
12+
13+
<Message type="important">
14+
We do not recommend using asymmetric encryption for anything other than key encryption.
15+
For all other purposes (encrypting large data or files), we recommend using Tink with Scaleway's Key Manager as explained [in the dedicated documentation](/key-manager/api-cli/encrypt-decrypt-data-with-km-dek/).
16+
</Message>
17+
18+
## Configuring your environment variables
19+
20+
Configuring your environment variables allows the Go application to authenticate and use Scaleway's API and Key Manager.
21+
22+
Open a terminal and paste the following commands to export your environment variables. Make sure that you add your **own variables**. You can also use a Scaleway configuration file.
23+
24+
```bash
25+
export SCW_ACCESS_KEY="<API-ACCESS-KEY>"
26+
export SCW_SECRET_KEY="<API-SECRET-KEY>"
27+
export SCW_DEFAULT_ORGANIZATION_ID="<Scaleway-Organization-ID>"
28+
export SCW_DEFAULT_REGION="<region>"
29+
export SCW_API_URL="<api-URL>"
30+
```
31+
32+
## Encrypting data
33+
34+
This operation takes place locally, ensuring the plaintext message never leaves your environment unprotected. The public key can be fetched using the Key Manager API, parsed, and used to encrypt data with RSA-OAEP and SHA-256 padding.
35+
36+
```golang
37+
// encryptAsymmetric encrypts data on your local machine using an 'rsa_oaep_3072_sha256' key retrieved from Scaleway Key Manager.
38+
//
39+
// Parameters:
40+
// - keyID: The unique identifier of the asymmetric key stored in Key Manager.
41+
// - message: The plaintext message that needs to be encrypted.
42+
//
43+
// Returns:
44+
// - error: An error if the encryption process fails, otherwise nil.
45+
func encryptAsymmetric(keyID string, message string) error {
46+
// Initialize the Scaleway client
47+
client, err := scw.NewClient(scw.WithEnv())
48+
if err != nil {
49+
panic(err)
50+
}
51+
kmsApi := key_manager.NewAPI(client)
52+
53+
// Retrieve the public key from Key Manager.
54+
response, err := kmsApi.GetPublicKey(&key_manager.GetPublicKeyRequest{
55+
KeyID: keyID,
56+
})
57+
if err != nil {
58+
return fmt.Errorf("failed to get public key: %w", err)
59+
}
60+
61+
// Parse the public key. This example assumes the public key is in the
62+
// RSA format.
63+
block, _ := pem.Decode([]byte(response.Pem))
64+
publicKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
65+
if err != nil {
66+
return fmt.Errorf("failed to parse public key: %w", err)
67+
}
68+
69+
// Convert the message into bytes. Cryptographic plaintexts and
70+
// ciphertexts are always byte arrays.
71+
plaintext := []byte(message)
72+
73+
// Encrypt data using the RSA public key.
74+
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, plaintext, nil)
75+
if err != nil {
76+
return fmt.Errorf("rsa.EncryptOAEP: %w", err)
77+
}
78+
79+
fmt.Printf("Encrypted ciphertext: %s\n", ciphertext)
80+
return nil
81+
}
82+
```
83+
84+
<Message type="note">
85+
- Encryption can also be performed using the [encrypt method of the Key Manager API](https://www.scaleway.com/en/developers/api/key-manager/#path-keys-encrypt-a-payload).
86+
- For asymmetric encryption, the maximum payload size allowed depends on the key algorithm used:
87+
- 190 bytes for `RSA_OAEP_2048_SHA256`
88+
- 318 bytes for `RSA_OAEP_3072_SHA256` and
89+
- 446 bytes for `RSA_OAEP_4096_SHA256`)
90+
</Message>
91+
92+
## Decrypting data
93+
94+
To retrieve the original message, you must send the encrypted ciphertext to Scaleway Key Manager, which uses the private portion of the asymmetric key to decrypt it. This ensures your private key remains secure within
95+
Scaleway’s infrastructure.
96+
97+
```golang
98+
99+
// decryptAsymmetric attempts to decrypt a given ciphertext using an 'rsa_oaep_3072_sha256' key from Key Manager.
100+
//
101+
// Parameters:
102+
// - keyID: The unique identifier of the asymmetric key stored in Key Manager.
103+
// - ciphertext: The encrypted data that needs to be decrypted.
104+
//
105+
// Returns:
106+
// - error: An error if the decryption process fails, otherwise nil.
107+
func decryptAsymmetric(keyID string, ciphertext []byte) error {
108+
// Initialize the Scaleway client
109+
client, err := scw.NewClient(scw.WithEnv())
110+
if err != nil {
111+
panic(err)
112+
}
113+
kmsApi := key_manager.NewAPI(client)
114+
115+
// Build the request.
116+
req := &key_manager.DecryptRequest{
117+
KeyID: keyID,
118+
Ciphertext: ciphertext,
119+
}
120+
121+
// Call the API.
122+
result, err := kmsApi.Decrypt(req)
123+
if err != nil {
124+
return fmt.Errorf("failed to decrypt ciphertext: %w", err)
125+
}
126+
127+
fmt.Printf("Decrypted plaintext: %s", result.Plaintext)
128+
return nil
129+
}
130+
```
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
title: Managing signatures using the Scaleway Go SDK and Key Manager
3+
description: Learn how to create and validate signatures using Key Manager with the Scaleway Go SDK.
4+
tags: key sensitive-data signature verification sign verify digest
5+
dates:
6+
validation: 2025-05-27
7+
posted: 2025-05-27
8+
---
9+
10+
This page shows you how to perform asymmetric signing and verification using Scaleway Key Manager. This documentation page shows you how to set up your environment to interact with the Scaleway API and Key Manager, and sign and verify messages using asymmetric keys.
11+
12+
## Configuring your environment variables
13+
14+
Configuring your environment variables allows the Go application to authenticate and use the Scaleway API and Key Manager.
15+
16+
Open a terminal and paste the following commands to export your environment variables. Make sure that you add your **own variables**. You can also use a Scaleway configuration file.
17+
18+
```bash
19+
export SCW_ACCESS_KEY="<API-ACCESS-KEY>"
20+
export SCW_SECRET_KEY="<API-SECRET-KEY>"
21+
export SCW_DEFAULT_ORGANIZATION_ID="<Scaleway-Organization-ID>"
22+
export SCW_DEFAULT_REGION="<region>"
23+
export SCW_API_URL="<api-URL>"
24+
```
25+
26+
## Creating a signature
27+
28+
```golang
29+
// signAsymmetric signs a plaintext message using a saved asymmetric private key 'ec_p256_sha256'
30+
// stored in Key Manager.
31+
//
32+
// Parameters:
33+
// - keyID: The unique identifier of the asymmetric key stored in Key Manager.
34+
// - message: The plaintext message that needs to be signed.
35+
//
36+
// Returns:
37+
// - err: An error if the signing process fails, otherwise nil.
38+
func signAsymmetric(keyID string, message string) error {
39+
// Initialize the Scaleway client
40+
client, err := scw.NewClient(scw.WithEnv())
41+
if err != nil {
42+
panic(err)
43+
}
44+
kmsApi := key_manager.NewAPI(client)
45+
46+
// Convert the message into bytes. Cryptographic plaintexts and ciphertexts are always byte arrays.
47+
plaintext := []byte(message)
48+
49+
// Calculate the digest of the message.
50+
// Note: Digest algorithm must match the key algorithm.
51+
// - Use SHA-256 for most algorithms (e.g., RSA_OAEP_3072_SHA256, EC_P256_SHA256).
52+
// - Use SHA-384 **only** for ECC_P384_SHA384.
53+
digest := sha256.New()
54+
if _, err = digest.Write(plaintext); err != nil {
55+
return fmt.Errorf("failed to create digest: %w", err)
56+
}
57+
58+
// Build the signing request.
59+
req := &key_manager.SignRequest{
60+
Digest: digest.Sum(nil),
61+
KeyID: keyID,
62+
}
63+
64+
// Call the API
65+
response, err = kmsApi.Sign(req)
66+
if err != nil {
67+
return fmt.Errorf("failed to sign digest: %w", err)
68+
}
69+
70+
fmt.Printf("Signed digest: %s", response.Signature)
71+
return nil
72+
}
73+
```
74+
75+
## Validating the signature
76+
77+
```golang
78+
// verifyAsymmetricSignature verifies that an 'ec_p256_sha256' signature is valid for a given message.
79+
//
80+
// Parameters:
81+
// - keyID: The unique identifier of the asymmetric key stored in Scaleway Key Manager.
82+
// - message: The plaintext message that was originally signed.
83+
// - signature: The signature obtained from a previous sign request.
84+
//
85+
// Returns:
86+
// - error: An error if the verification process fails or if the signature is invalid, otherwise nil.
87+
func verifyAsymmetricSignature(keyID string, message, signature []byte) error {
88+
// Initialize the Scaleway client
89+
client, err := scw.NewClient(scw.WithEnv())
90+
if err != nil {
91+
panic(err)
92+
}
93+
kmsApi := key_manager.NewAPI(client)
94+
95+
// Verify signature.
96+
// Calculate the digest of the message.
97+
digest := sha256.New()
98+
if _, err = digest.Write(message); err != nil {
99+
return fmt.Errorf("failed to create digest: %w", err)
100+
}
101+
102+
verify, err := kmsApi.Verify(&key_manager.VerifyRequest{
103+
KeyID: keyID,
104+
Digest: digest.Sum(nil),
105+
Signature: signature,
106+
})
107+
if err != nil {
108+
return err
109+
}
110+
111+
if verify.Valid {
112+
fmt.Printf("Verified signature!")
113+
}
114+
115+
return nil
116+
}
117+
```

0 commit comments

Comments
 (0)