Beispiel #1
0
        public byte[] Decrypt(byte[] aad, byte[] cek, byte[] iv, byte[] cipherText, byte[] authTag)
        {
            Ensure.BitSize(cek, keyLength, string.Format("AES-CBC with HMAC algorithm expected key of size {0} bits, but was given {1} bits", keyLength, cek.Length * 8L));

            byte[] hmacKey = Arrays.FirstHalf(cek);
            byte[] aesKey  = Arrays.SecondHalf(cek);

            // Check MAC
            byte[] expectedAuthTag = ComputeAuthTag(aad, iv, cipherText, hmacKey);

            if (!Arrays.ConstantTimeEquals(expectedAuthTag, authTag))
            {
                throw new IntegrityException("Authentication tag do not match.");
            }

            try
            {
                using (Aes aes = Aes.Create())
                {
                    aes.Key = aesKey;
                    aes.IV  = iv;

                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
                        {
                            using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write))
                            {
                                cs.Write(cipherText, 0, cipherText.Length);
                                cs.FlushFinalBlock();

                                return(ms.ToArray());
                            }
                        }
                    }
                }
            }
            catch (CryptographicException e)
            {
                throw new EncryptionException("Unable to decrypt content", e);
            }
        }
Beispiel #2
0
        public byte[][] Encrypt(byte[] aad, byte[] plainText, byte[] cek)
        {
            Ensure.BitSize(cek, keyLength, string.Format("AES-CBC with HMAC algorithm expected key of size {0} bits, but was given {1} bits", keyLength, cek.Length * 8L));

            byte[] hmacKey = Arrays.FirstHalf(cek);
            byte[] aesKey  = Arrays.SecondHalf(cek);

            byte[] iv = Arrays.Random();

            byte[] cipherText;

            try
            {
                using (Aes aes = Aes.Create())
                {
                    aes.Key = aesKey;
                    aes.IV  = iv;

                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
                        {
                            using (CryptoStream encrypt = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                            {
                                encrypt.Write(plainText, 0, plainText.Length);
                                encrypt.FlushFinalBlock();

                                cipherText = ms.ToArray();
                            }
                        }
                    }
                }
            }
            catch (CryptographicException e)
            {
                throw new EncryptionException("Unable to encrypt content.", e);
            }

            byte[] authTag = ComputeAuthTag(aad, iv, cipherText, hmacKey);

            return(new[] { iv, cipherText, authTag });
        }
Beispiel #3
0
        public static byte[] Unwrap(byte[] encryptedCek, byte[] kek)
        {
            Ensure.MinBitSize(encryptedCek, 128, "AesKeyWrap.Unwrap() expects content length not less than 128 bits, but was {0}", encryptedCek.Length * 8);
            Ensure.Divisible(encryptedCek.Length, 8, "AesKeyWrap.Unwrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", encryptedCek.Length * 8);

            // 1) Initialize variables
            byte[][] c = Arrays.Slice(encryptedCek, 8);
            byte[]   a = c[0];                         //   Set A = C[0]
            byte[][] r = new byte[c.Length - 1][];

            for (int i = 1; i < c.Length; i++)         //   For i = 1 to n
            {
                r[i - 1] = c[i];                       //       R[i] = C[i]
            }
            long n = r.Length;

            // 2) Calculate intermediate values
            for (long j = 5; j >= 0; j--)                                   // For j = 5 to 0
            {
                for (long i = n - 1; i >= 0; i--)                           //   For i = n to 1
                {
                    long t = n * j + i + 1;

                    a = Arrays.Xor(a, t);
                    byte[] B = AesDec(kek, Arrays.Concat(a, r[i]));     //     B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
                    a    = Arrays.FirstHalf(B);                         //     A = MSB(64, B)
                    r[i] = Arrays.SecondHalf(B);                        //     R[i] = LSB(64, B)
                }
            }

            // 3) Output the results
            if (!Arrays.ConstantTimeEquals(DefaultIV, a))   // If A is an appropriate initial value
            {
                throw new IntegrityException("AesKeyWrap integrity check failed.");
            }

            // For i = 1 to n
            return(Arrays.Concat(r));                        //    P[i] = R[i]
        }
 public byte[] Decrypt(byte[] aad, byte[] cek, byte[] iv, byte[] cipherText, byte[] authTag)
 {
     byte[] array;
     Ensure.BitSize(cek, this.keyLength, string.Format("AES-CBC with HMAC algorithm expected key of size {0} bits, but was given {1} bits", this.keyLength, (int)cek.Length * 8), new object[0]);
     byte[] numArray  = Arrays.FirstHalf(cek);
     byte[] numArray1 = Arrays.SecondHalf(cek);
     if (!Arrays.ConstantTimeEquals(this.ComputeAuthTag(aad, iv, cipherText, numArray), authTag))
     {
         throw new IntegrityException("Authentication tag do not match.");
     }
     try
     {
         using (Aes ae = Aes.Create())
         {
             ae.Key = numArray1;
             ae.IV  = iv;
             using (MemoryStream memoryStream = new MemoryStream())
             {
                 using (ICryptoTransform cryptoTransform = ae.CreateDecryptor(ae.Key, ae.IV))
                 {
                     using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
                     {
                         cryptoStream.Write(cipherText, 0, (int)cipherText.Length);
                         cryptoStream.FlushFinalBlock();
                         array = memoryStream.ToArray();
                     }
                 }
             }
         }
     }
     catch (CryptographicException cryptographicException)
     {
         throw new EncryptionException("Unable to decrypt content", cryptographicException);
     }
     return(array);
 }
 private byte[] ComputeAuthTag(byte[] aad, byte[] iv, byte[] cipherText, byte[] hmacKey)
 {
     byte[] bytes    = Arrays.LongToBytes((long)((int)aad.Length * 8));
     byte[] numArray = Arrays.Concat(new byte[][] { aad, iv, cipherText, bytes });
     return(Arrays.FirstHalf(this.hashAlgorithm.Sign(numArray, hmacKey)));
 }