Esempio n. 1
0
 internal static void ValidateEncryptionAlgorithm(KeyEncryptionKeyAlgorithm encryptionAlgorithm)
 {
     if (encryptionAlgorithm != KeyEncryptionKeyAlgorithm.RSA_OAEP)
     {
         throw new MicrosoftDataEncryptionException(InvalidKeyAlgorithm.FormatInvariant(encryptionAlgorithm, KeyEncryptionKeyAlgorithm.RSA_OAEP.ToString()));
     }
 }
Esempio n. 2
0
        /// <summary>
        /// This function uses the asymmetric key specified by the key path
        /// and encrypts an unencrypted data encryption key with RSA encryption algorithm.
        /// </summary>
        /// <param name="encryptionKeyId">Identifier of an asymmetric key in Azure Key Vault</param>
        /// <param name="algorithm">The encryption algorithm.</param>
        /// <param name="key">The plaintext key.</param>
        /// <returns>Encrypted data encryption key</returns>
        public override byte[] WrapKey(string encryptionKeyId, KeyEncryptionKeyAlgorithm algorithm, byte[] key)
        {
            // Validate the input parameters
            ValidateNonEmptyAKVPath(encryptionKeyId, isSystemOp: true);
            ValidateEncryptionAlgorithm(algorithm);
            key.ValidateNotNull(nameof(key));
            ValidateDataEncryptionKeyNotEmpty(key);

            // Also validates whether the key is RSA one or not and then get the key size
            KeyCryptographer.AddKey(encryptionKeyId);
            int keySizeInBytes = KeyCryptographer.GetKeySize(encryptionKeyId);

            // Construct the encryptedDataEncryptionKey
            // Format is
            //          firstVersion + keyPathLength + ciphertextLength + keyPath + ciphertext  + signature

            // Get the Unicode encoded bytes of cultureinvariant lower case keyEncryptionKeyPath
            byte[] keyEncryptionKeyPathBytes = Encoding.Unicode.GetBytes(encryptionKeyId.ToLowerInvariant());
            byte[] keyPathLength             = BitConverter.GetBytes((short)keyEncryptionKeyPathBytes.Length);

            // Encrypt the plain text
            byte[] cipherText       = KeyCryptographer.WrapKey(keyWrapAlgorithm, key, encryptionKeyId);
            byte[] cipherTextLength = BitConverter.GetBytes((short)cipherText.Length);

            if (cipherText.Length != keySizeInBytes)
            {
                throw new MicrosoftDataEncryptionException(CipherTextLengthMismatch);
            }

            // Compute message
            // SHA-2-256(version + keyPathLength + ciphertextLength + keyPath + ciphertext)
            byte[] message = firstVersion.Concat(keyPathLength).Concat(cipherTextLength).Concat(keyEncryptionKeyPathBytes).Concat(cipherText).ToArray();

            // Sign the message
            byte[] signature = KeyCryptographer.SignData(message, encryptionKeyId);

            if (signature.Length != keySizeInBytes)
            {
                throw new MicrosoftDataEncryptionException(HashLengthMismatch);
            }

            ValidateSignature(encryptionKeyId, message, signature);

            return(message.Concat(signature).ToArray());
        }
Esempio n. 3
0
        /// <summary>
        /// This function uses the asymmetric key specified by the key path
        /// and decrypts an encrypted data dencryption key with RSA encryption algorithm.
        /// </summary>
        /// <param name="encryptionKeyId">Identifier of an asymmetric key in Azure Key Vault</param>
        /// <param name="algorithm">The encryption algorithm.</param>
        /// <param name="encryptedKey">The ciphertext key.</param>
        /// <returns>Plain text data encryption key</returns>
        public override byte[] UnwrapKey(string encryptionKeyId, KeyEncryptionKeyAlgorithm algorithm, byte[] encryptedKey)
        {
            // Validate the input parameters
            ValidateNonEmptyAKVPath(encryptionKeyId, isSystemOp: true);
            ValidateEncryptionAlgorithm(algorithm);
            encryptedKey.ValidateNotNull(nameof(encryptedKey));
            encryptedKey.ValidateNotEmpty(nameof(encryptedKey));
            ValidateVersionByte(encryptedKey[0], firstVersion[0]);

            return(GetOrCreateDataEncryptionKey(encryptedKey.ToHexString(), DecryptEncryptionKey));

            byte[] DecryptEncryptionKey()
            {
                // Also validates whether the key is RSA one or not and then get the key size
                KeyCryptographer.AddKey(encryptionKeyId);

                int keySizeInBytes = KeyCryptographer.GetKeySize(encryptionKeyId);

                // Get key path length
                int    currentIndex  = firstVersion.Length;
                ushort keyPathLength = BitConverter.ToUInt16(encryptedKey, currentIndex);

                currentIndex += sizeof(ushort);

                // Get ciphertext length
                ushort cipherTextLength = BitConverter.ToUInt16(encryptedKey, currentIndex);

                currentIndex += sizeof(ushort);

                // Skip KeyPath
                // KeyPath exists only for troubleshooting purposes and doesnt need validation.
                currentIndex += keyPathLength;

                // validate the ciphertext length
                if (cipherTextLength != keySizeInBytes)
                {
                    throw new MicrosoftDataEncryptionException(InvalidCiphertextLengthTemplate.FormatInvariant(cipherTextLength, keySizeInBytes, encryptionKeyId));
                }

                // Validate the signature length
                int signatureLength = encryptedKey.Length - currentIndex - cipherTextLength;

                if (signatureLength != keySizeInBytes)
                {
                    throw new MicrosoftDataEncryptionException(InvalidSignatureLengthTemplate.FormatInvariant(signatureLength, keySizeInBytes, encryptionKeyId));
                }

                // Get ciphertext
                byte[] cipherText = encryptedKey.Skip(currentIndex).Take(cipherTextLength).ToArray();
                currentIndex += cipherTextLength;

                // Get signature
                byte[] signature = encryptedKey.Skip(currentIndex).Take(signatureLength).ToArray();

                // Compute the message to validate the signature
                byte[] message = encryptedKey.Take(encryptedKey.Length - signatureLength).ToArray();

                if (null == message)
                {
                    throw new MicrosoftDataEncryptionException(NullHash);
                }

                if (!KeyCryptographer.VerifyData(message, signature, encryptionKeyId))
                {
                    throw new MicrosoftDataEncryptionException(InvalidSignatureTemplate.FormatInvariant(encryptionKeyId));
                }

                return(KeyCryptographer.UnwrapKey(keyWrapAlgorithm, cipherText, encryptionKeyId));
            }
        }
 public override byte[] WrapKey(string masterKeyPath, KeyEncryptionKeyAlgorithm encryptionAlgorithm, byte[] columnEncryptionKey)
 {
     throw new NotImplementedException();
 }
 public override byte[] UnwrapKey(string masterKeyPath, KeyEncryptionKeyAlgorithm encryptionAlgorithm, byte[] encryptedColumnEncryptionKey)
 {
     return(GetOrCreateDataEncryptionKey(encryptedColumnEncryptionKey.ToHexString(), DecryptEncryptionKey));
 public override byte[] WrapKey(string masterKeyPath, KeyEncryptionKeyAlgorithm encryptionAlgorithm, byte[] key)
 {
     byte[] encryptedkey = key.Select(b => (byte)(b + 1)).ToArray();
     return(encryptedkey);
 }
 public override byte[] UnwrapKey(string masterKeyPath, KeyEncryptionKeyAlgorithm encryptionAlgorithm, byte[] encryptedKey)
 {
     byte[] plainkey = encryptedKey.Select(b => (byte)(b - 1)).ToArray();
     return(plainkey);
 }