/// <summary> /// Returns encryption instructions to encrypt content with AES/GCM/NoPadding algorithm /// Creates encryption key used for AES/GCM/NoPadding and encrypt it with AES/GCM /// Encrypted key follows nonce(12 bytes) + key cipher text(16 or 32 bytes) + tag(16 bytes) format /// Tag is appended by the AES/GCM cipher with encryption process /// </summary> /// <param name="materials"></param> /// <returns></returns> private static EncryptionInstructions EncryptEnvelopeKeyUsingSymmetricKeyV2(EncryptionMaterialsV2 materials) { var aes = materials.SymmetricProvider as Aes; if (aes == null) { throw new NotSupportedException("AES is the only supported algorithm with this method."); } switch (materials.SymmetricProviderType) { case SymmetricAlgorithmType.AesGcm: { var aesObject = Aes.Create(); var nonce = aesObject.IV.Take(DefaultNonceSize).ToArray(); var associatedText = Encoding.UTF8.GetBytes(XAmzAesGcmCekAlgValue); var cipher = AesGcmUtils.CreateCipher(true, materials.SymmetricProvider.Key, DefaultTagBitsLength, nonce, associatedText); var envelopeKey = cipher.DoFinal(aesObject.Key); var encryptedEnvelopeKey = nonce.Concat(envelopeKey).ToArray(); var instructions = new EncryptionInstructions(materials.MaterialsDescription, aesObject.Key, encryptedEnvelopeKey, nonce, XAmzWrapAlgAesGcmValue, XAmzAesGcmCekAlgValue); return(instructions); } default: { throw new NotSupportedException($"{materials.SymmetricProviderType} isn't supported with SymmetricProvider"); } } }
/// <summary> /// Generates an instruction that will be used to encrypt an object /// using materials with the KMSKeyID set. /// </summary> /// <param name="kmsClient"> /// Used to call KMS to generate a data key. /// </param> /// <param name="materials"> /// The encryption materials to be used to encrypt and decrypt data. /// </param> /// <returns> /// The instruction that will be used to encrypt an object. /// </returns> internal static async System.Threading.Tasks.Task <EncryptionInstructions> GenerateInstructionsForKMSMaterialsV2Async(IAmazonKeyManagementService kmsClient, EncryptionMaterialsV2 materials) { if (materials.KMSKeyID == null) { throw new ArgumentNullException(nameof(materials.KMSKeyID), KmsKeyIdNullMessage); } switch (materials.KmsType) { case KmsType.KmsContext: { var nonce = new byte[DefaultNonceSize]; // Generate nonce, and get both the key and the encrypted key from KMS. RandomNumberGenerator.Create().GetBytes(nonce); var result = await kmsClient.GenerateDataKeyAsync(materials.KMSKeyID, materials.MaterialsDescription, KMSKeySpec).ConfigureAwait(false); var instructions = new EncryptionInstructions(materials.MaterialsDescription, result.KeyPlaintext, result.KeyCiphertext, nonce, XAmzWrapAlgKmsContextValue, XAmzAesGcmCekAlgValue); return(instructions); } default: throw new NotSupportedException($"{materials.KmsType} is not supported for KMS Key Id {materials.KMSKeyID}"); } }
private static EncryptionInstructions EncryptEnvelopeKeyUsingAsymmetricKeyPairV2(EncryptionMaterialsV2 materials) { var rsa = materials.AsymmetricProvider as RSA; if (rsa == null) { throw new NotSupportedException("RSA is the only supported algorithm with this method."); } switch (materials.AsymmetricProviderType) { case AsymmetricAlgorithmType.RsaOaepSha1: { var aesObject = Aes.Create(); var nonce = aesObject.IV.Take(DefaultNonceSize).ToArray(); var envelopeKeyToEncrypt = EnvelopeKeyForDataKey(aesObject.Key); var cipher = RsaUtils.CreateRsaOaepSha1Cipher(true, rsa); var encryptedEnvelopeKey = cipher.DoFinal(envelopeKeyToEncrypt); var instructions = new EncryptionInstructions(materials.MaterialsDescription, aesObject.Key, encryptedEnvelopeKey, nonce, XAmzWrapAlgRsaOaepSha1, XAmzAesGcmCekAlgValue); return(instructions); } default: { throw new NotSupportedException($"{materials.AsymmetricProviderType} isn't supported with AsymmetricProvider"); } } }
/// <summary> /// Generates an instruction that will be used to encrypt an object /// using materials with the AsymmetricProvider or SymmetricProvider set. /// </summary> /// <param name="materials"> /// The encryption materials to be used to encrypt and decrypt data. /// </param> /// <returns> /// The instruction that will be used to encrypt an object. /// </returns> internal static EncryptionInstructions GenerateInstructionsForNonKmsMaterialsV2(EncryptionMaterialsV2 materials) { // Generate the IV and key, and encrypt the key locally. if (materials.AsymmetricProvider != null) { return(EncryptEnvelopeKeyUsingAsymmetricKeyPairV2(materials)); } if (materials.SymmetricProvider != null) { return(EncryptEnvelopeKeyUsingSymmetricKeyV2(materials)); } throw new ArgumentException("Error generating encryption instructions. " + "EncryptionMaterials must have the AsymmetricProvider or SymmetricProvider set."); }