在中使用 Amazon S3 加密的 AWS KMS 金鑰 AWS SDK for .NET - AWS SDK for .NET

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在中使用 Amazon S3 加密的 AWS KMS 金鑰 AWS SDK for .NET

此範例說明如何使用 AWS Key Management Service 金鑰加密 Amazon S3 物件。應用程式會建立客戶主金鑰 (CMK),並使用它來建立用於用戶端加密的 AmazonS3 EncryptionClient V2 物件。應用程式使用該用戶端從現有 Amazon S3 儲存貯體中的指定文字檔建立加密物件。然後解密物件並顯示其內容。

警告

名為的類似類已AmazonS3EncryptionClient被棄用,並且比該AmazonS3EncryptionClientV2類的安全性較低。若要移轉使用的既有程式碼AmazonS3EncryptionClient,請參閱S3 加密用戶端移轉

建立加密材料

下列程式碼片段會建立包含 KMS 金鑰識別碼的EncryptionMaterials物件。

本主題結尾的範例顯示了使用中的這個程式碼片段。

// Create a customer master key (CMK) and store the result CreateKeyResponse createKeyResponse = await new AmazonKeyManagementServiceClient().CreateKeyAsync(new CreateKeyRequest()); var kmsEncryptionContext = new Dictionary<string, string>(); var kmsEncryptionMaterials = new EncryptionMaterialsV2( createKeyResponse.KeyMetadata.KeyId, KmsType.KmsContext, kmsEncryptionContext);

建立和加密 Amazon S3 物件

下列程式碼片段會建AmazonS3EncryptionClientV2立使用先前建立的加密材料的物件。然後,它會使用用戶端建立和加密新的 Amazon S3 物件。

本主題結尾的範例顯示了使用中的這個程式碼片段。

// // Method to create and encrypt an object in an S3 bucket static async Task<GetObjectResponse> CreateAndRetrieveObjectAsync( EncryptionMaterialsV2 materials, string bucketName, string fileName, string itemName) { // CryptoStorageMode.ObjectMetadata is required for KMS EncryptionMaterials var config = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy) { StorageMode = CryptoStorageMode.ObjectMetadata }; var s3EncClient = new AmazonS3EncryptionClientV2(config, materials); // Create, encrypt, and put the object await s3EncClient.PutObjectAsync(new PutObjectRequest { BucketName = bucketName, Key = itemName, ContentBody = File.ReadAllText(fileName) }); // Get, decrypt, and return the object return await s3EncClient.GetObjectAsync(new GetObjectRequest { BucketName = bucketName, Key = itemName }); }

完整的代碼

本節顯示此範例的相關參考資料和完整程式碼。

using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using Amazon.Extensions.S3.Encryption; using Amazon.Extensions.S3.Encryption.Primitives; using Amazon.S3.Model; using Amazon.KeyManagementService; using Amazon.KeyManagementService.Model; namespace KmsS3Encryption { // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class to store text in an encrypted S3 object. class Program { private const int MaxArgs = 3; public static async Task Main(string[] args) { // Parse the command line and show help if necessary var parsedArgs = CommandLine.Parse(args); if((parsedArgs.Count == 0) || (parsedArgs.Count > MaxArgs)) { PrintHelp(); return; } // Get the application arguments from the parsed list string bucketName = CommandLine.GetArgument(parsedArgs, null, "-b", "--bucket-name"); string fileName = CommandLine.GetArgument(parsedArgs, null, "-f", "--file-name"); string itemName = CommandLine.GetArgument(parsedArgs, null, "-i", "--item-name"); if(string.IsNullOrEmpty(bucketName) || (string.IsNullOrEmpty(fileName))) CommandLine.ErrorExit( "\nOne or more of the required arguments is missing or incorrect." + "\nRun the command with no arguments to see help."); if(!File.Exists(fileName)) CommandLine.ErrorExit($"\nThe given file {fileName} doesn't exist."); if(string.IsNullOrEmpty(itemName)) itemName = Path.GetFileName(fileName); // Create a customer master key (CMK) and store the result CreateKeyResponse createKeyResponse = await new AmazonKeyManagementServiceClient().CreateKeyAsync(new CreateKeyRequest()); var kmsEncryptionContext = new Dictionary<string, string>(); var kmsEncryptionMaterials = new EncryptionMaterialsV2( createKeyResponse.KeyMetadata.KeyId, KmsType.KmsContext, kmsEncryptionContext); // Create the object in the bucket, then display the content of the object var putObjectResponse = await CreateAndRetrieveObjectAsync(kmsEncryptionMaterials, bucketName, fileName, itemName); Stream stream = putObjectResponse.ResponseStream; StreamReader reader = new StreamReader(stream); Console.WriteLine(reader.ReadToEnd()); } // // Method to create and encrypt an object in an S3 bucket static async Task<GetObjectResponse> CreateAndRetrieveObjectAsync( EncryptionMaterialsV2 materials, string bucketName, string fileName, string itemName) { // CryptoStorageMode.ObjectMetadata is required for KMS EncryptionMaterials var config = new AmazonS3CryptoConfigurationV2(SecurityProfile.V2AndLegacy) { StorageMode = CryptoStorageMode.ObjectMetadata }; var s3EncClient = new AmazonS3EncryptionClientV2(config, materials); // Create, encrypt, and put the object await s3EncClient.PutObjectAsync(new PutObjectRequest { BucketName = bucketName, Key = itemName, ContentBody = File.ReadAllText(fileName) }); // Get, decrypt, and return the object return await s3EncClient.GetObjectAsync(new GetObjectRequest { BucketName = bucketName, Key = itemName }); } // // Command-line help private static void PrintHelp() { Console.WriteLine( "\nUsage: KmsS3Encryption -b <bucket-name> -f <file-name> [-i <item-name>]" + "\n -b, --bucket-name: The name of an existing S3 bucket." + "\n -f, --file-name: The name of a text file with content to encrypt and store in S3." + "\n -i, --item-name: The name you want to use for the item." + "\n If item-name isn't given, file-name will be used."); } } // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = // Class that represents a command line on the console or terminal. // (This is the same for all examples. When you have seen it once, you can ignore it.) static class CommandLine { // // Method to parse a command line of the form: "--key value" or "-k value". // // Parameters: // - args: The command-line arguments passed into the application by the system. // // Returns: // A Dictionary with string Keys and Values. // // If a key is found without a matching value, Dictionary.Value is set to the key // (including the dashes). // If a value is found without a matching key, Dictionary.Key is set to "--NoKeyN", // where "N" represents sequential numbers. public static Dictionary<string,string> Parse(string[] args) { var parsedArgs = new Dictionary<string,string>(); int i = 0, n = 0; while(i < args.Length) { // If the first argument in this iteration starts with a dash it's an option. if(args[i].StartsWith("-")) { var key = args[i++]; var value = key; // Check to see if there's a value that goes with this option? if((i < args.Length) && (!args[i].StartsWith("-"))) value = args[i++]; parsedArgs.Add(key, value); } // If the first argument in this iteration doesn't start with a dash, it's a value else { parsedArgs.Add("--NoKey" + n.ToString(), args[i++]); n++; } } return parsedArgs; } // // Method to get an argument from the parsed command-line arguments // // Parameters: // - parsedArgs: The Dictionary object returned from the Parse() method (shown above). // - defaultValue: The default string to return if the specified key isn't in parsedArgs. // - keys: An array of keys to look for in parsedArgs. public static string GetArgument( Dictionary<string,string> parsedArgs, string defaultReturn, params string[] keys) { string retval = null; foreach(var key in keys) if(parsedArgs.TryGetValue(key, out retval)) break; return retval ?? defaultReturn; } // // Method to exit the application with an error. public static void ErrorExit(string msg, int code=1) { Console.WriteLine("\nError"); Console.WriteLine(msg); Environment.Exit(code); } } }

其他考量

  • 您可以檢查此示例的結果。若要這麼做,請前往 Amazon S3 主控台並開啟您提供給應用程式的儲存貯體。然後找到新對象,下載它,然後在文本編輯器中打開它。

  • 亞馬遜 S3 EncryptionClient V2 類實現了與標準AmazonS3Client類相同的接口。這樣可以更輕鬆地將代碼移植到AmazonS3EncryptionClientV2類,以便在客戶端中自動透明地進行加密和解密。

  • 使用金鑰做為主金 AWS KMS 鑰的一個優點是您不需要儲存和管理自己的主金鑰;這是由 AWS. 第二個優點是,的AmazonS3EncryptionClientV2 AWS SDK for .NET 類別可與的AmazonS3EncryptionClientV2類別互操作。 AWS SDK for Java這表示您可以使用加密 AWS SDK for Java 並使用解密 AWS SDK for .NET,反之亦然。

    注意

    AmazonS3EncryptionClientV2類別僅在中繼資料模式下執行時才 AWS SDK for .NET 支援 KMS 主金鑰。的AmazonS3EncryptionClientV2類別的指令檔案模 AWS SDK for .NET 式與的AmazonS3EncryptionClientV2類別不相容 AWS SDK for Java。