コード例 #1
0
        private static byte[] PRF(EncryptionType type, byte[] protocolKey, byte[] truncated)
        {
            byte[] prf = Encoding.UTF8.GetBytes("prf");
            switch (type)
            {
            case EncryptionType.AES256_CTS_HMAC_SHA1_96:
            {
                byte[] temp          = AesKey.DK(protocolKey, prf, AesKeyType.Aes256BitsKey);
                byte[] initialVector = new byte[ConstValue.AES_BLOCK_SIZE];
                CipherTextStealingMode aesCtsCrypto = CryptoUtility.CreateAesCtsCrypto(temp, initialVector);
                byte[] encryptedData = aesCtsCrypto.EncryptFinal(truncated, 0, truncated.Length);
                return(encryptedData);
            }

            case EncryptionType.AES128_CTS_HMAC_SHA1_96:
            {
                byte[] temp = AesKey.DK(protocolKey, prf, AesKeyType.Aes128BitsKey);
                break;
            }

            default:
                throw new NotSupportedException("Encryption type not support");
            }

            throw new NotImplementedException();
        }
コード例 #2
0
        /// <summary>
        /// Decrypt in aes128-cts-hmac-sha1-96 or aes256-cts-hmac-sha1-96
        /// </summary>
        /// <param name="key">key data</param>
        /// <param name="cipher">cipher data to be decrypted</param>
        /// <param name="usage">key usage number</param>
        /// <param name="aesKeyType">aes key type (128bit/256bit)</param>
        /// <param name="getToBeSignedDateCallback">
        /// A callback to get to-be-signed data.
        /// The method will use decrypted data directly if this parameter is null.
        /// </param>
        /// <returns>the decrypted data</returns>
        public static byte[] Decrypt(
            byte[] key,
            byte[] cipher,
            int usage,
            AesKeyType aesKeyType,
            GetToBeSignedDataFunc getToBeSignedDateCallback)
        {
            // check inputs
            if (null == key)
            {
                throw new ArgumentNullException("key");
            }
            if (null == cipher)
            {
                throw new ArgumentNullException("cipher");
            }

            // the cipher has two parts: encrypted(confounder + plain) + hmac
            byte[] encryptedData = ArrayUtility.SubArray <byte>(
                cipher, 0, cipher.Length - ConstValue.HMAC_HASH_OUTPUT_SIZE);
            byte[] hmacData = ArrayUtility.SubArray <byte>(
                cipher, cipher.Length - ConstValue.HMAC_HASH_OUTPUT_SIZE);

            // use ke key (the encryption key) to decrypt
            byte[] ke            = AesKey.MakeDerivedKey(key, usage, DerivedKeyType.Ke, aesKeyType);
            byte[] initialVector = new byte[ConstValue.AES_BLOCK_SIZE];
            CipherTextStealingMode aesCtsCrypto = CryptoUtility.CreateAesCtsCrypto(ke, initialVector);

            byte[] decryptedData = aesCtsCrypto.DecryptFinal(encryptedData, 0, encryptedData.Length);

            byte[] toBeSignedData;
            if (getToBeSignedDateCallback != null)
            {
                toBeSignedData = getToBeSignedDateCallback(decryptedData);
            }
            else
            {
                toBeSignedData = decryptedData;
            }

            // use ki key (the integrity key) to verify hmac data
            byte[] ki = AesKey.MakeDerivedKey(key, usage, DerivedKeyType.Ki, aesKeyType);
            byte[] expectedHmacData = CryptoUtility.ComputeHmacSha1(ki, toBeSignedData);
            expectedHmacData = ArrayUtility.SubArray <byte>(expectedHmacData, 0, ConstValue.HMAC_HASH_OUTPUT_SIZE);
            if (!ArrayUtility.CompareArrays <byte>(hmacData, expectedHmacData))
            {
                throw new FormatException(
                          "Decryption: failed integrity check in hmac checksum.");
            }

            // remove confounder data
            decryptedData = ArrayUtility.SubArray <byte>(decryptedData, ConstValue.AES_BLOCK_SIZE,
                                                         decryptedData.Length - ConstValue.AES_BLOCK_SIZE);
            return(decryptedData);
        }
コード例 #3
0
        /// <summary>
        /// Encrypt in aes128-cts-hmac-sha1-96 or aes256-cts-hmac-sha1-96
        /// </summary>
        /// <param name="key">key data</param>
        /// <param name="plain">plain data to be encrypted</param>
        /// <param name="usage">key usage number</param>
        /// <param name="aesKeyType">aes key type (128bit/256bit)</param>
        /// <param name="getToBeSignedDateCallback">
        /// A callback to get to-be-signed data.
        /// The method will use plain-text data directly if this parameter is null.
        /// </param>
        /// <returns>the encrypted data</returns>
        public static byte[] Encrypt(
            byte[] key,
            byte[] plain,
            int usage,
            AesKeyType aesKeyType,
            GetToBeSignedDataFunc getToBeSignedDateCallback)
        {
            // check inputs
            if (null == key)
            {
                throw new ArgumentNullException("key");
            }
            if (null == plain)
            {
                throw new ArgumentNullException("plain");
            }

            // add confounder data
            byte[] plainData = ArrayUtility.ConcatenateArrays(
                CryptoUtility.CreateConfounder(ConstValue.AES_BLOCK_SIZE),
                plain);

            // use ke key (the encryption key) to encrypt the plain data
            byte[] ke            = AesKey.MakeDerivedKey(key, usage, DerivedKeyType.Ke, aesKeyType);
            byte[] initialVector = new byte[ConstValue.AES_BLOCK_SIZE];
            CipherTextStealingMode aesCtsCrypto = CryptoUtility.CreateAesCtsCrypto(ke, initialVector);

            byte[] encryptedData = aesCtsCrypto.EncryptFinal(plainData, 0, plainData.Length);

            byte[] toBeSignedData;
            if (getToBeSignedDateCallback != null)
            {
                toBeSignedData = getToBeSignedDateCallback(plainData);
            }
            else
            {
                toBeSignedData = plainData;
            }

            // use ki key (the integrity key) to generate checksum
            byte[] ki       = AesKey.MakeDerivedKey(key, usage, DerivedKeyType.Ki, aesKeyType);
            byte[] hmacData = CryptoUtility.ComputeHmacSha1(ki, toBeSignedData);
            hmacData = ArrayUtility.SubArray <byte>(hmacData, 0, ConstValue.HMAC_HASH_OUTPUT_SIZE);

            // result: encryptedData + hmacData
            return(ArrayUtility.ConcatenateArrays(encryptedData, hmacData));
        }
コード例 #4
0
        /// <summary>
        /// DR is the random-octet generation function described in RFC 3961
        /// [RFC 3961 section 5.1 A Key Derivation Function]
        /// </summary>
        /// <param name="baseKey">the base key which is to be derived from</param>
        /// <param name="wellKnownConstant">the "well-known constant"</param>
        /// <param name="aesKeyType">AES key type which decides key size</param>
        /// <returns>the pseudorandom octets</returns>
        private static byte[] DR(
            byte[] baseKey,
            byte[] wellKnownConstant,
            AesKeyType aesKeyType)
        {
            // to be encrypted data
            byte[] toBeEncrypted = new byte[wellKnownConstant.Length];
            wellKnownConstant.CopyTo(toBeEncrypted, 0);

            // n-fold the "well-known constant" if needed
            if (wellKnownConstant.Length != ConstValue.AES_BLOCK_SIZE)
            {
                toBeEncrypted = NFold(wellKnownConstant, ConstValue.AES_BLOCK_SIZE * ConstValue.BYTE_SIZE);
            }

            // AES key size
            uint aesKeySize = (uint)aesKeyType / ConstValue.BYTE_SIZE;

            // initialize key array
            byte[] rawkey = new byte[aesKeySize];

            // count means the total number of bytes has been copy to the rawkey.
            // length means how length of bytes should be copy to the rawkey array.
            uint count  = 0;
            uint length = 0;

            // The initialCipherVector should be all zeros.
            byte[] initialCipherVector = new byte[ConstValue.AES_BLOCK_SIZE];

            // AES-CTS encryptor
            CipherTextStealingMode aesCtsCrypto = CryptoUtility.CreateAesCtsCrypto(baseKey, initialCipherVector);

            while (count < aesKeySize)
            {
                byte[] cipherBlock = aesCtsCrypto.EncryptFinal(toBeEncrypted, 0, toBeEncrypted.Length);
                length = (aesKeySize - count <= cipherBlock.Length ? (aesKeySize - count) : Convert.ToUInt32(cipherBlock.Length));
                Array.Copy(cipherBlock, 0, rawkey, count, length);
                count        += length;
                toBeEncrypted = cipherBlock;
            }
            return(rawkey);
        }