-
Notifications
You must be signed in to change notification settings - Fork 241
feat(key_manager): add documentation about asymmetric features #4981
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Draft
mmrqs
wants to merge
4
commits into
main
Choose a base branch
from
feat/KMS-58
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
905eaf0
feat(key_manager): add documentation about creating and verify digita…
a1e3d8f
docs(review): menu titles
nerda-codes c40f42d
docs(review): review of en/decrypting data with asym key
nerda-codes 4145004
Update sign-verify-key-with-go-sdk.mdx
nerda-codes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
pages/key-manager/api-cli/encrypt-decrypt-asymmetric-key-with-go-sdk.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
--- | ||
meta: | ||
title: Encrypting and decrypting data with an asymmetric key | ||
description: Learn how to encrypt and decrypt data with an asymmetric key using Key Manager and the Scaleway Go SDK. | ||
content: | ||
h1: Encrypting and decrypting data with an asymmetric key | ||
paragraph: Learn how to encrypt and decrypt data with an asymmetric key using Key Manager and the Scaleway Go SDK. | ||
tags: key sensitive-data encrypt decrypt asymmetric digest | ||
dates: | ||
validation: 2025-05-27 | ||
posted: 2025-05-27 | ||
--- | ||
|
||
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/). | ||
|
||
|
||
<Message type="important"> | ||
We do not recommend using asymmetric encryption for anything other than key encryption. | ||
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/). | ||
</Message> | ||
|
||
## Configuring your environment variables | ||
|
||
Configuring your environment variables allows the Go application to authenticate and use Scaleway's API and Key Manager. | ||
|
||
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. | ||
|
||
```bash | ||
export SCW_ACCESS_KEY="<API-ACCESS-KEY>" | ||
export SCW_SECRET_KEY="<API-SECRET-KEY>" | ||
export SCW_DEFAULT_ORGANIZATION_ID="<Scaleway-Organization-ID>" | ||
export SCW_DEFAULT_REGION="<region>" | ||
export SCW_API_URL="<api-URL>" | ||
``` | ||
|
||
## Encrypting data | ||
|
||
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. | ||
|
||
```golang | ||
// encryptAsymmetric encrypts data on your local machine using an 'rsa_oaep_3072_sha256' key retrieved from Scaleway Key Manager. | ||
// | ||
// Parameters: | ||
// - keyID: The unique identifier of the asymmetric key stored in Key Manager. | ||
// - message: The plaintext message that needs to be encrypted. | ||
// | ||
// Returns: | ||
// - error: An error if the encryption process fails, otherwise nil. | ||
func encryptAsymmetric(keyID string, message string) error { | ||
// Initialize the Scaleway client | ||
client, err := scw.NewClient(scw.WithEnv()) | ||
if err != nil { | ||
panic(err) | ||
} | ||
kmsApi := key_manager.NewAPI(client) | ||
|
||
// Retrieve the public key from Key Manager. | ||
response, err := kmsApi.GetPublicKey(&key_manager.GetPublicKeyRequest{ | ||
KeyID: keyID, | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("failed to get public key: %w", err) | ||
} | ||
|
||
// Parse the public key. This example assumes the public key is in the | ||
// RSA format. | ||
block, _ := pem.Decode([]byte(response.Pem)) | ||
publicKey, err := x509.ParsePKCS1PublicKey(block.Bytes) | ||
if err != nil { | ||
return fmt.Errorf("failed to parse public key: %w", err) | ||
} | ||
|
||
// Convert the message into bytes. Cryptographic plaintexts and | ||
// ciphertexts are always byte arrays. | ||
plaintext := []byte(message) | ||
|
||
// Encrypt data using the RSA public key. | ||
ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, plaintext, nil) | ||
if err != nil { | ||
return fmt.Errorf("rsa.EncryptOAEP: %w", err) | ||
} | ||
|
||
fmt.Printf("Encrypted ciphertext: %s\n", ciphertext) | ||
return nil | ||
} | ||
``` | ||
|
||
<Message type="note"> | ||
- 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). | ||
- For asymmetric encryption, the maximum payload size allowed depends on the key algorithm used: | ||
- 190 bytes for `RSA_OAEP_2048_SHA256` | ||
- 318 bytes for `RSA_OAEP_3072_SHA256` and | ||
- 446 bytes for `RSA_OAEP_4096_SHA256`) | ||
</Message> | ||
|
||
## Decrypting data | ||
|
||
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 | ||
Scaleway’s infrastructure. | ||
|
||
```golang | ||
|
||
// decryptAsymmetric attempts to decrypt a given ciphertext using an 'rsa_oaep_3072_sha256' key from Key Manager. | ||
// | ||
// Parameters: | ||
// - keyID: The unique identifier of the asymmetric key stored in Key Manager. | ||
// - ciphertext: The encrypted data that needs to be decrypted. | ||
// | ||
// Returns: | ||
// - error: An error if the decryption process fails, otherwise nil. | ||
func decryptAsymmetric(keyID string, ciphertext []byte) error { | ||
// Initialize the Scaleway client | ||
client, err := scw.NewClient(scw.WithEnv()) | ||
if err != nil { | ||
panic(err) | ||
} | ||
kmsApi := key_manager.NewAPI(client) | ||
|
||
// Build the request. | ||
req := &key_manager.DecryptRequest{ | ||
KeyID: keyID, | ||
Ciphertext: ciphertext, | ||
} | ||
|
||
// Call the API. | ||
result, err := kmsApi.Decrypt(req) | ||
if err != nil { | ||
return fmt.Errorf("failed to decrypt ciphertext: %w", err) | ||
} | ||
|
||
fmt.Printf("Decrypted plaintext: %s", result.Plaintext) | ||
return nil | ||
} | ||
``` |
121 changes: 121 additions & 0 deletions
121
pages/key-manager/api-cli/sign-verify-key-with-go-sdk.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
--- | ||
meta: | ||
title: Managing signatures using the Scaleway Go SDK and Key Manager | ||
description: Learn how to create and validate signatures using Key Manager with the Scaleway Go SDK. | ||
content: | ||
h1: Managing signatures using the Scaleway Go SDK and Key Manager | ||
paragraph: Learn how to create and validate signatures using Key Manager with the Scaleway Go SDK. | ||
tags: key sensitive-data signature verification sign verify digest | ||
dates: | ||
validation: 2025-05-27 | ||
posted: 2025-05-27 | ||
--- | ||
|
||
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. | ||
|
||
## Configuring your environment variables | ||
|
||
Configuring your environment variables allows the Go application to authenticate and use the Scaleway API and Key Manager. | ||
|
||
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. | ||
|
||
```bash | ||
export SCW_ACCESS_KEY="<API-ACCESS-KEY>" | ||
export SCW_SECRET_KEY="<API-SECRET-KEY>" | ||
export SCW_DEFAULT_ORGANIZATION_ID="<Scaleway-Organization-ID>" | ||
export SCW_DEFAULT_REGION="<region>" | ||
export SCW_API_URL="<api-URL>" | ||
``` | ||
|
||
## Creating a signature | ||
|
||
```golang | ||
// signAsymmetric signs a plaintext message using a saved asymmetric private key 'ec_p256_sha256' | ||
// stored in Key Manager. | ||
// | ||
// Parameters: | ||
// - keyID: The unique identifier of the asymmetric key stored in Key Manager. | ||
// - message: The plaintext message that needs to be signed. | ||
// | ||
// Returns: | ||
// - err: An error if the signing process fails, otherwise nil. | ||
func signAsymmetric(keyID string, message string) error { | ||
// Initialize the Scaleway client | ||
client, err := scw.NewClient(scw.WithEnv()) | ||
if err != nil { | ||
panic(err) | ||
} | ||
kmsApi := key_manager.NewAPI(client) | ||
|
||
// Convert the message into bytes. Cryptographic plaintexts and ciphertexts are always byte arrays. | ||
plaintext := []byte(message) | ||
|
||
// Calculate the digest of the message. | ||
// Note: Digest algorithm must match the key algorithm. | ||
// - Use SHA-256 for most algorithms (e.g., RSA_OAEP_3072_SHA256, EC_P256_SHA256). | ||
// - Use SHA-384 **only** for ECC_P384_SHA384. | ||
digest := sha256.New() | ||
if _, err = digest.Write(plaintext); err != nil { | ||
return fmt.Errorf("failed to create digest: %w", err) | ||
} | ||
|
||
// Build the signing request. | ||
req := &key_manager.SignRequest{ | ||
Digest: digest.Sum(nil), | ||
KeyID: keyID, | ||
} | ||
|
||
// Call the API | ||
response, err = kmsApi.Sign(req) | ||
if err != nil { | ||
return fmt.Errorf("failed to sign digest: %w", err) | ||
} | ||
|
||
fmt.Printf("Signed digest: %s", response.Signature) | ||
return nil | ||
} | ||
``` | ||
|
||
## Validating the signature | ||
|
||
```golang | ||
// verifyAsymmetricSignature verifies that an 'ec_p256_sha256' signature is valid for a given message. | ||
// | ||
// Parameters: | ||
// - keyID: The unique identifier of the asymmetric key stored in Scaleway Key Manager. | ||
// - message: The plaintext message that was originally signed. | ||
// - signature: The signature obtained from a previous sign request. | ||
// | ||
// Returns: | ||
// - error: An error if the verification process fails or if the signature is invalid, otherwise nil. | ||
func verifyAsymmetricSignature(keyID string, message, signature []byte) error { | ||
// Initialize the Scaleway client | ||
client, err := scw.NewClient(scw.WithEnv()) | ||
if err != nil { | ||
panic(err) | ||
} | ||
kmsApi := key_manager.NewAPI(client) | ||
|
||
// Verify signature. | ||
// Calculate the digest of the message. | ||
digest := sha256.New() | ||
if _, err = digest.Write(message); err != nil { | ||
return fmt.Errorf("failed to create digest: %w", err) | ||
} | ||
|
||
verify, err := kmsApi.Verify(&key_manager.VerifyRequest{ | ||
KeyID: keyID, | ||
Digest: digest.Sum(nil), | ||
Signature: signature, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if verify.Valid { | ||
fmt.Printf("Verified signature!") | ||
} | ||
|
||
return nil | ||
} | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.