在 中使用 AWS KMS 金鑰進行 Amazon S3 加密 適用於 .NET 的 AWS SDK - 適用於 .NET 的 AWS SDK (V4)

第 4 版 (V4) 適用於 .NET 的 AWS SDK 已發行!

如需有關中斷變更和遷移應用程式的資訊,請參閱遷移主題

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

在 中使用 AWS KMS 金鑰進行 Amazon S3 加密 適用於 .NET 的 AWS SDK

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

警告

稱為 的類似類別AmazonS3EncryptionClient已棄用,且比 AmazonS3EncryptionClientV2類別較不安全。若要遷移使用 的現有程式碼AmazonS3EncryptionClient,請參閱 S3 加密用戶端遷移

建立加密資料

下列程式碼片段會建立包含 KMS 金鑰 ID 的 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 主控台,並開啟您提供給應用程式的儲存貯體。然後尋找新物件、下載它,然後在文字編輯器中開啟它。

  • AmazonS3EncryptionClientV2 類別實作與標準AmazonS3Client類別相同的界面。這可讓您更輕鬆地將程式碼移植到 AmazonS3EncryptionClientV2類別,以便在用戶端中自動且透明地進行加密和解密。

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

    注意

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