Skip to content

Commit bfaad2c

Browse files
auto commit
1 parent 34120dc commit bfaad2c

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-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+
}

0 commit comments

Comments
 (0)