/// <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");
            }
        }
Example #3
0
        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);
        }