1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
package s3crypto_test
import (
"bytes"
"fmt"
"io/ioutil"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/kms"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3crypto"
)
// ExampleNewEncryptionClientV2_migration00 provides a migration example for how users can migrate from the V1
// encryption client to the V2 encryption client. This example demonstrates how an application using the `kms` key wrap
// algorithm with `AES/CBC/PKCS5Padding` can migrate their application to `kms+context` key wrapping with
// `AES/GCM/NoPadding` content encryption.
func ExampleNewEncryptionClientV2_migration00() {
sess := session.Must(session.NewSession())
kmsClient := kms.New(sess)
cmkID := "1234abcd-12ab-34cd-56ef-1234567890ab"
// Usage of NewKMSKeyGenerator (kms) key wrapping algorithm must be migrated to NewKMSContextKeyGenerator (kms+context) key wrapping algorithm
//
// cipherDataGenerator := s3crypto.NewKMSKeyGenerator(kmsClient, cmkID)
cipherDataGenerator := s3crypto.NewKMSContextKeyGenerator(kmsClient, cmkID, s3crypto.MaterialDescription{})
// Usage of AESCBCContentCipherBuilder (AES/CBC/PKCS5Padding) must be migrated to AESGCMContentCipherBuilder (AES/GCM/NoPadding)
//
// contentCipherBuilder := s3crypto.AESCBCContentCipherBuilder(cipherDataGenerator, s3crypto.AESCBCPadder)
contentCipherBuilder := s3crypto.AESGCMContentCipherBuilderV2(cipherDataGenerator)
// Construction of an encryption client should be done using NewEncryptionClientV2
//
// encryptionClient := s3crypto.NewEncryptionClient(sess, contentCipherBuilder)
encryptionClient, err := s3crypto.NewEncryptionClientV2(sess, contentCipherBuilder)
if err != nil {
fmt.Printf("failed to construct encryption client: %v", err)
return
}
_, err = encryptionClient.PutObject(&s3.PutObjectInput{
Bucket: aws.String("your_bucket"),
Key: aws.String("your_key"),
Body: bytes.NewReader([]byte("your content")),
})
if err != nil {
fmt.Printf("put object error: %v\n", err)
return
}
fmt.Println("put object completed")
}
// ExampleNewEncryptionClientV2_migration01 provides a more advanced migration example for how users can
// migrate from the V1 encryption client to the V2 encryption client using more complex client construction.
func ExampleNewEncryptionClientV2_migration01() {
sess := session.Must(session.NewSession())
kmsClient := kms.New(sess)
cmkID := "1234abcd-12ab-34cd-56ef-1234567890ab"
cipherDataGenerator := s3crypto.NewKMSContextKeyGenerator(kmsClient, cmkID, s3crypto.MaterialDescription{})
contentCipherBuilder := s3crypto.AESGCMContentCipherBuilderV2(cipherDataGenerator)
// Overriding of the encryption client options is possible by passing in functional arguments that override the
// provided EncryptionClientOptions.
//
// encryptionClient := s3crypto.NewEncryptionClient(cipherDataGenerator, contentCipherBuilder, func(o *s3crypto.EncryptionClient) {
// o.S3Client = s3.New(sess, &aws.Config{Region: aws.String("us-west-2")}),
// })
encryptionClient, err := s3crypto.NewEncryptionClientV2(sess, contentCipherBuilder, func(o *s3crypto.EncryptionClientOptions) {
o.S3Client = s3.New(sess, &aws.Config{Region: aws.String("us-west-2")})
})
if err != nil {
fmt.Printf("failed to construct encryption client: %v", err)
return
}
_, err = encryptionClient.PutObject(&s3.PutObjectInput{
Bucket: aws.String("your_bucket"),
Key: aws.String("your_key"),
Body: bytes.NewReader([]byte("your content")),
})
if err != nil {
fmt.Printf("put object error: %v\n", err)
return
}
fmt.Println("put object completed")
}
// ExampleNewDecryptionClientV2_migration00 provides a migration example for how users can migrate
// from the V1 Decryption Clients to the V2 Decryption Clients.
func ExampleNewDecryptionClientV2_migration00() {
sess := session.Must(session.NewSession())
// Construction of an decryption client must be done using NewDecryptionClientV2
// The V2 decryption client is able to decrypt object encrypted by the V1 client.
//
// decryptionClient := s3crypto.NewDecryptionClient(sess)
// The V2 decryption client requires you to explicitly register the key wrap algorithms and content encryption algorithms
// that you want to explicitly support decryption for.
registry := s3crypto.NewCryptoRegistry()
kmsClient := kms.New(sess)
// If you need support for unwrapping data keys wrapped using the `kms` wrap algorithm you can use RegisterKMSWrapWithAnyCMK.
// Alternatively you may use RegisterKMSWrapWithCMK if you wish to limit KMS decrypt calls to a specific CMK.
if err := s3crypto.RegisterKMSWrapWithAnyCMK(registry, kmsClient); err != nil {
fmt.Printf("error: %v", err)
return
}
// For unwrapping data keys wrapped using the new `kms+context` key wrap algorithm you can use RegisterKMSContextWrapWithAnyCMK.
// Alternatively you may use RegisterKMSWrapWithCMK if you wish to limit KMS decrypt calls to a specific CMK.
if err := s3crypto.RegisterKMSContextWrapWithAnyCMK(registry, kmsClient); err != nil {
fmt.Printf("error: %v", err)
return
}
// If you need to decrypt objects encrypted using the V1 AES/CBC/PCKS5Padding cipher you can do so with RegisterAESCBCContentCipher
if err := s3crypto.RegisterAESCBCContentCipher(registry, s3crypto.AESCBCPadder); err != nil {
fmt.Printf("error: %v", err)
return
}
// For decrypting objects encrypted in V1 or V2 using AES/GCM/NoPadding cipher you can do so with RegisterAESGCMContentCipher.
if err := s3crypto.RegisterAESGCMContentCipher(registry); err != nil {
fmt.Printf("error: %v", err)
return
}
// Instantiate a new decryption client, and provided the Wrap, cek, and Padder that have been registered
// with your desired algorithms.
decryptionClient, err := s3crypto.NewDecryptionClientV2(sess, registry)
if err != nil {
fmt.Printf("error: %v", err)
return
}
getObject, err := decryptionClient.GetObject(&s3.GetObjectInput{
Bucket: aws.String("your_bucket"),
Key: aws.String("your_key"),
})
if err != nil {
fmt.Printf("get object error: %v\n", err)
return
}
_, err = ioutil.ReadAll(getObject.Body)
if err != nil {
fmt.Printf("error reading object: %v\n", err)
}
fmt.Println("get object completed")
}
// ExampleNewDecryptionClientV2_migration01 provides a more advanced migration example for how users can
// migrate from the V1 decryption client to the V2 decryption client using more complex client construction.
func ExampleNewDecryptionClientV2_migration01() {
sess := session.Must(session.NewSession())
// Construction of an decryption client must be done using NewDecryptionClientV2
// The V2 decryption client is able to decrypt object encrypted by the V1 client.
//
// decryptionClient := s3crypto.NewDecryptionClient(sess, func(o *s3crypto.DecryptionClient) {
// o.S3Client = s3.New(sess, &aws.Config{Region: aws.String("us-west-2")})
//})
registry := s3crypto.NewCryptoRegistry()
kmsClient := kms.New(sess)
if err := s3crypto.RegisterKMSWrapWithAnyCMK(registry, kmsClient); err != nil {
fmt.Printf("error: %v", err)
return
}
// If you need to decrypt objects encrypted using AES/GCM/NoPadding cipher you can do so with RegisterAESGCMContentCipher
if err := s3crypto.RegisterAESGCMContentCipher(registry); err != nil {
fmt.Printf("error: %v", err)
return
}
decryptionClient, err := s3crypto.NewDecryptionClientV2(sess, registry, func(o *s3crypto.DecryptionClientOptions) {
o.S3Client = s3.New(sess, &aws.Config{Region: aws.String("us-west-2")})
})
if err != nil {
fmt.Printf("error: %v", err)
return
}
getObject, err := decryptionClient.GetObject(&s3.GetObjectInput{
Bucket: aws.String("your_bucket"),
Key: aws.String("your_key"),
})
if err != nil {
fmt.Printf("get object error: %v\n", err)
return
}
_, err = ioutil.ReadAll(getObject.Body)
if err != nil {
fmt.Printf("error reading object: %v\n", err)
}
fmt.Println("get object completed")
}
|