Skip to content

Commit 34120dc

Browse files
Examples
1 parent 5c4e4c0 commit 34120dc

File tree

3 files changed

+289
-0
lines changed

3 files changed

+289
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package keyring
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
8+
"github.com/aws/aws-sdk-go-v2/aws"
9+
"github.com/aws/aws-sdk-go-v2/config"
10+
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
11+
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
12+
"github.com/aws/aws-sdk-go-v2/service/kms"
13+
14+
mpl "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated"
15+
mpltypes "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes"
16+
"github.com/aws/aws-database-encryption-sdk-dynamodb/awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes"
17+
"github.com/aws/aws-database-encryption-sdk-dynamodb/awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes"
18+
"github.com/aws/aws-database-encryption-sdk-dynamodb/dbesdkmiddleware"
19+
"github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dbesdk/examples/utils"
20+
kmstypes "github.com/aws/aws-sdk-go-v2/service/kms/types"
21+
)
22+
23+
func PutItemGetItem(kmsRsaKeyID string, kmsRSAPublicKeyFileName string) {
24+
ddbTableName := "DynamoDbEncryptionInterceptorTestTableCS"
25+
// 1. Create the aws kms client
26+
cfg, err := config.LoadDefaultConfig(context.TODO())
27+
if err != nil {
28+
panic(err)
29+
}
30+
kmsClient := kms.NewFromConfig(cfg, func(o *kms.Options) {
31+
o.Region = "us-west-2"
32+
})
33+
// 2. Initialize the mpl client
34+
matProv, err := mpl.NewClient(
35+
mpltypes.MaterialProvidersConfig{},
36+
)
37+
if err != nil {
38+
panic(err)
39+
}
40+
// 3. Load UTF-8 encoded public key PEM file.
41+
// You may have an RSA public key file already defined.
42+
// If not, this method will call the KMS RSA key, retrieve its public key,
43+
// and store it in a PEM file for example use.
44+
if !utils.FileExists(kmsRSAPublicKeyFileName) {
45+
err = writePublicKeyPemForRsaKey(kmsRsaKeyID, kmsRSAPublicKeyFileName)
46+
if err != nil {
47+
panic(err)
48+
}
49+
}
50+
kmsRSAPublicKey, err := os.ReadFile(kmsRSAPublicKeyFileName)
51+
if err != nil {
52+
panic(err)
53+
}
54+
55+
// 4. Create the keyring
56+
awsKmsRSAKeyringInput := mpltypes.CreateAwsKmsRsaKeyringInput{
57+
KmsClient: kmsClient,
58+
KmsKeyId: kmsRsaKeyID,
59+
PublicKey: kmsRSAPublicKey,
60+
EncryptionAlgorithm: kmstypes.EncryptionAlgorithmSpecRsaesOaepSha256,
61+
}
62+
keyring, err := matProv.CreateAwsKmsRsaKeyring(context.Background(), awsKmsRSAKeyringInput)
63+
if err != nil {
64+
panic(err)
65+
}
66+
67+
// 2. Configure attribute actions for encryption/signing
68+
attributeActions := map[string]awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoAction{
69+
"partition_key": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionSignOnly, // Partition key must be SIGN_ONLY
70+
"sort_key": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionSignOnly, // Sort key must be SIGN_ONLY
71+
"sensitive_data": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionEncryptAndSign,
72+
}
73+
74+
// 3. Configure table encryption
75+
allowedUnsignedAttributePrefix := ":"
76+
sortKeyName := "sort_key"
77+
algorithmSuiteID := mpltypes.DBEAlgorithmSuiteIdAlgAes256GcmHkdfSha512CommitKeySymsigHmacSha384
78+
tableConfig := awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes.DynamoDbTableEncryptionConfig{
79+
LogicalTableName: ddbTableName,
80+
PartitionKeyName: "partition_key",
81+
SortKeyName: &sortKeyName,
82+
AttributeActionsOnEncrypt: attributeActions,
83+
Keyring: keyring,
84+
AllowedUnsignedAttributePrefix: &allowedUnsignedAttributePrefix,
85+
AlgorithmSuiteId: &algorithmSuiteID,
86+
}
87+
88+
tableConfigsMap := make(map[string]awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes.DynamoDbTableEncryptionConfig)
89+
tableConfigsMap[ddbTableName] = tableConfig
90+
listOfTableConfigs := awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes.DynamoDbTablesEncryptionConfig{
91+
TableEncryptionConfigs: tableConfigsMap,
92+
}
93+
// 4. Create encrypted DynamoDB client
94+
dbEsdkMiddleware, err := dbesdkmiddleware.NewDBEsdkMiddleware(listOfTableConfigs)
95+
if err != nil {
96+
panic(err)
97+
}
98+
ddb := dynamodb.NewFromConfig(cfg, dbEsdkMiddleware.CreateMiddleware())
99+
100+
// 5. Put an encrypted item
101+
item := map[string]types.AttributeValue{
102+
"partition_key": &types.AttributeValueMemberS{Value: "awsKmsRsaKeyringItem"},
103+
"sort_key": &types.AttributeValueMemberN{Value: "0"},
104+
"sensitive_data": &types.AttributeValueMemberS{Value: "encrypt and sign me!"},
105+
}
106+
107+
putInput := &dynamodb.PutItemInput{
108+
TableName: aws.String(ddbTableName),
109+
Item: item,
110+
}
111+
112+
_, err = ddb.PutItem(context.TODO(), putInput)
113+
if err != nil {
114+
panic(err)
115+
}
116+
117+
// 6. Get and decrypt the item
118+
key := map[string]types.AttributeValue{
119+
"partition_key": &types.AttributeValueMemberS{Value: "awsKmsRsaKeyringItem"},
120+
"sort_key": &types.AttributeValueMemberN{Value: "0"},
121+
}
122+
123+
getInput := &dynamodb.GetItemInput{
124+
TableName: aws.String(ddbTableName),
125+
Key: key,
126+
ConsistentRead: aws.Bool(true),
127+
}
128+
129+
result, err := ddb.GetItem(context.TODO(), getInput)
130+
if err != nil {
131+
panic(err)
132+
}
133+
fmt.Println(result.Item["partition_key"].(*types.AttributeValueMemberS).Value)
134+
// Verify the decrypted item
135+
if result.Item["sensitive_data"].(*types.AttributeValueMemberS).Value != "encrypt and sign me!" {
136+
panic("unexpected value for attribute1")
137+
}
138+
}
139+
140+
func writePublicKeyPemForRsaKey(rsaKeyArn, filename string) error {
141+
cfg, err := config.LoadDefaultConfig(context.TODO())
142+
if err != nil {
143+
return err
144+
}
145+
146+
kmsClient := kms.NewFromConfig(cfg)
147+
resp, err := kmsClient.GetPublicKey(context.TODO(), &kms.GetPublicKeyInput{
148+
KeyId: aws.String(rsaKeyArn),
149+
})
150+
if err != nil {
151+
return err
152+
}
153+
return utils.WritePublicKey(resp.PublicKey, filename)
154+
}

Examples/runtimes/go/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package main
2+
3+
import (
4+
"github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dbesdk/examples/keyring"
5+
"github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dbesdk/examples/misc"
6+
"github.com/aws/aws-database-encryption-sdk-dynamodb/releases/go/dbesdk/examples/utils"
7+
)
8+
9+
func main() {
10+
misc.PutItemGetItem()
11+
keyring.PutItemGetItem(utils.TestKmsRsaKeyID(), utils.RsaPublicKeyFilename())
12+
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package misc
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/aws/aws-database-encryption-sdk-dynamodb/awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes"
8+
"github.com/aws/aws-database-encryption-sdk-dynamodb/awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes"
9+
"github.com/aws/aws-sdk-go-v2/aws"
10+
"github.com/aws/aws-sdk-go-v2/config"
11+
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
12+
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
13+
"github.com/aws/aws-sdk-go-v2/service/kms"
14+
15+
mpl "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated"
16+
mpltypes "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes"
17+
"github.com/aws/aws-database-encryption-sdk-dynamodb/dbesdkmiddleware"
18+
)
19+
20+
func PutItemGetItem() {
21+
// Get configuration values from environment or test utils
22+
kmsKeyID := "arn:aws:kms:us-west-2:658956600833:key/b3537ef1-d8dc-4780-9f5a-55776cbb2f7f"
23+
ddbTableName := "DynamoDbEncryptionInterceptorTestTableCS"
24+
25+
// 1. Create a Keyring using AWS KMS
26+
cfg, err := config.LoadDefaultConfig(context.TODO())
27+
if err != nil {
28+
panic(err)
29+
}
30+
kmsClient := kms.NewFromConfig(cfg, func(o *kms.Options) {
31+
o.Region = "us-west-2"
32+
})
33+
// Step 2: Initialize the mpl client
34+
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{})
35+
if err != nil {
36+
panic(err)
37+
}
38+
// Step 3: Create the keyring
39+
awsKmsKeyringInput := mpltypes.CreateAwsKmsKeyringInput{
40+
KmsClient: kmsClient,
41+
KmsKeyId: kmsKeyID,
42+
}
43+
keyring, err := matProv.CreateAwsKmsKeyring(context.Background(), awsKmsKeyringInput)
44+
if err != nil {
45+
panic(err)
46+
}
47+
48+
// 2. Configure attribute actions for encryption/signing
49+
attributeActions := map[string]awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoAction{
50+
"partition_key": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionSignOnly, // Partition key must be SIGN_ONLY
51+
"sort_key": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionSignOnly, // Sort key must be SIGN_ONLY
52+
"attribute1": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionEncryptAndSign,
53+
"attribute2": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionSignOnly,
54+
":attribute3": awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes.CryptoActionDoNothing,
55+
}
56+
57+
// 3. Configure table encryption
58+
allowedUnsignedAttributePrefix := ":"
59+
sortKeyName := "sort_key"
60+
algorithmSuiteId := mpltypes.DBEAlgorithmSuiteIdAlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384
61+
tableConfig := awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes.DynamoDbTableEncryptionConfig{
62+
LogicalTableName: ddbTableName,
63+
PartitionKeyName: "partition_key",
64+
SortKeyName: &sortKeyName,
65+
AttributeActionsOnEncrypt: attributeActions,
66+
Keyring: keyring,
67+
AllowedUnsignedAttributePrefix: &allowedUnsignedAttributePrefix,
68+
AlgorithmSuiteId: &algorithmSuiteId,
69+
}
70+
71+
tableConfigsMap := make(map[string]awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes.DynamoDbTableEncryptionConfig)
72+
tableConfigsMap[ddbTableName] = tableConfig
73+
listOfTableConfigs := awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes.DynamoDbTablesEncryptionConfig{
74+
TableEncryptionConfigs: tableConfigsMap,
75+
}
76+
// 4. Create encrypted DynamoDB client
77+
dbEsdkMiddleware, err := dbesdkmiddleware.NewDBEsdkMiddleware(listOfTableConfigs)
78+
if err != nil {
79+
panic(err)
80+
}
81+
ddb := dynamodb.NewFromConfig(cfg, dbEsdkMiddleware.CreateMiddleware())
82+
83+
// 5. Put an encrypted item
84+
item := map[string]types.AttributeValue{
85+
"partition_key": &types.AttributeValueMemberS{Value: "BasicPutGetExample"},
86+
"sort_key": &types.AttributeValueMemberN{Value: "0"},
87+
"attribute1": &types.AttributeValueMemberS{Value: "encrypt and sign me!"},
88+
"attribute2": &types.AttributeValueMemberS{Value: "sign me!"},
89+
":attribute3": &types.AttributeValueMemberS{Value: "ignore me!"},
90+
}
91+
92+
putInput := &dynamodb.PutItemInput{
93+
TableName: aws.String(ddbTableName),
94+
Item: item,
95+
}
96+
97+
_, err = ddb.PutItem(context.TODO(), putInput)
98+
if err != nil {
99+
panic(err)
100+
}
101+
102+
// 6. Get and decrypt the item
103+
key := map[string]types.AttributeValue{
104+
"partition_key": &types.AttributeValueMemberS{Value: "BasicPutGetExample"},
105+
"sort_key": &types.AttributeValueMemberN{Value: "0"},
106+
}
107+
108+
getInput := &dynamodb.GetItemInput{
109+
TableName: aws.String(ddbTableName),
110+
Key: key,
111+
ConsistentRead: aws.Bool(true),
112+
}
113+
114+
result, err := ddb.GetItem(context.TODO(), getInput)
115+
if err != nil {
116+
panic(err)
117+
}
118+
// Verify the decrypted item
119+
if result.Item["attribute1"].(*types.AttributeValueMemberS).Value != "encrypt and sign me!" {
120+
panic("unexpected value for attribute1")
121+
}
122+
fmt.Println(result.Item["attribute1"].(*types.AttributeValueMemberS).Value)
123+
}

0 commit comments

Comments
 (0)