/// <inheritdoc /> public XElement Decrypt(XElement encryptedElement) { GaxPreconditions.CheckNotNull(encryptedElement, nameof(encryptedElement)); XElement payloadElement = encryptedElement.Element(PayloadElement); XAttribute kmsKeyName = encryptedElement.Attribute(KmsKeyNameAttribute); XAttribute localKeyDataAttribute = encryptedElement.Attribute(LocalKeyDataAttribute); GaxPreconditions.CheckArgument(payloadElement != null, nameof(encryptedElement), "Expected '{0}' element", PayloadElement); GaxPreconditions.CheckArgument(kmsKeyName != null, nameof(encryptedElement), "Expected '{0}' attribute", KmsKeyNameAttribute); GaxPreconditions.CheckArgument(localKeyDataAttribute != null, nameof(encryptedElement), "Expected '{0}' attribute", LocalKeyDataAttribute); CryptoKeyName cryptoKeyName = CryptoKeyName.Parse(kmsKeyName.Value); ByteString encryptedLocalKeyData = ByteString.FromBase64(localKeyDataAttribute.Value); ByteString plaintextLocalKeyData = _kmsClient.Decrypt(cryptoKeyName, encryptedLocalKeyData).Plaintext; SymmetricKey key = SymmetricKey.Parser.ParseFrom(plaintextLocalKeyData); using (var algorithm = CreateLocalKey(key)) { byte[] encryptedPayload = Convert.FromBase64String(payloadElement.Value); using (var decryptor = algorithm.CreateDecryptor()) { byte[] plaintextPayload = decryptor.TransformFinalBlock(encryptedPayload, 0, encryptedPayload.Length); using (var stream = new MemoryStream(plaintextPayload)) { return(XElement.Load(stream)); } } } }
private static SymmetricAlgorithm CreateLocalKey(SymmetricKey key) { switch (key.KeyDataCase) { case SymmetricKey.KeyDataOneofCase.AesKey: var aesKey = key.AesKey; var aes = Aes.Create(); aes.Key = aesKey.Key.ToByteArray(); aes.IV = aesKey.IV.ToByteArray(); return(aes); default: throw new ArgumentException($"Unknown key type: {key.KeyDataCase}. Check you're using the latest Google.Cloud.AspNetCore.DataProtection.Kms package"); } }
private (SymmetricKey proto, SymmetricAlgorithm algorithm) CreateLocalKey() { // Currently we only support AES. var algorithm = Aes.Create(); algorithm.GenerateKey(); algorithm.GenerateIV(); var proto = new SymmetricKey { AesKey = new AesKey { IV = ByteString.CopyFrom(algorithm.IV), Key = ByteString.CopyFrom(algorithm.Key) } }; return(proto, algorithm); }