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