Beispiel #1
0
        private static readonly byte[] DefaultIV = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 }; // http://www.ietf.org/rfc/rfc3394.txt (see 2.2.3)

        public static byte[] Wrap(byte[] cek, byte[] kek)
        {
            Ensure.MinBitSize(cek, 128, "AesKeyWrap.Wrap() expects content length not less than 128 bits, but was {0}", cek.Length * 8);
            Ensure.Divisible(cek.Length, 8, "AesKeyWrap.Wrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", cek.Length * 8);

            // 1) Initialize variables
            byte[]   a = DefaultIV;                     // Set A = IV, an initial value
            byte[][] r = Arrays.Slice(cek, 8);          // For i = 1 to n
            //     R[0][i] = P[i]
            long n = r.Length;

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

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

                    a = Arrays.Xor(a, t);
                }
            }
            // 3) Output the results
            byte[][] c = new byte[n + 1][];
            c[0] = a;                                     //  Set C[0] = A
            for (long i = 1; i <= n; i++)                 //  For i = 1 to n
            {
                c[i] = r[i - 1];                          //     C[i] = R[i]
            }
            return(Arrays.Concat(c));
        }
Beispiel #2
0
        public static byte[] Wrap(byte[] cek, byte[] kek)
        {
            Ensure.MinBitSize(cek, 128, "AesKeyWrap.Wrap() expects content length not less than 128 bits, but was {0}", new object[] { (int)cek.Length * 8 });
            Ensure.Divisible((int)cek.Length, 8, "AesKeyWrap.Wrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", new object[] { (int)cek.Length * 8 });
            byte[]   defaultIV = AesKeyWrap.DefaultIV;
            byte[][] numArray  = Arrays.Slice(cek, 8);
            long     length    = (long)((int)numArray.Length);

            for (long i = (long)0; i < (long)6; i += (long)1)
            {
                for (long j = (long)0; j < length; j += (long)1)
                {
                    long   num       = length * i + j + (long)1;
                    byte[] numArray1 = AesKeyWrap.AesEnc(kek, Arrays.Concat(new byte[][] { defaultIV, numArray[checked (j)] }));
                    defaultIV             = Arrays.FirstHalf(numArray1);
                    numArray[checked (j)] = Arrays.SecondHalf(numArray1);
                    defaultIV             = Arrays.Xor(defaultIV, num);
                }
            }
            byte[][] numArray2 = new byte[checked (length + 1)][];
            numArray2[0] = defaultIV;
            for (long k = (long)1; k <= length; k += (long)1)
            {
                numArray2[checked (k)] = numArray[checked (k - (long)1)];
            }
            return(Arrays.Concat(numArray2));
        }
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}", new object[] { (int)encryptedCek.Length * 8 });
            Ensure.Divisible((int)encryptedCek.Length, 8, "AesKeyWrap.Unwrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", new object[] { (int)encryptedCek.Length * 8 });
            byte[][] numArray  = Arrays.Slice(encryptedCek, 8);
            byte[]   numArray1 = numArray[0];
            byte[][] numArray2 = new byte[(int)numArray.Length - 1][];
            for (int i = 1; i < (int)numArray.Length; i++)
            {
                numArray2[i - 1] = numArray[i];
            }
            long length = (long)((int)numArray2.Length);

            for (long j = (long)5; j >= (long)0; j -= (long)1)
            {
                for (long k = length - (long)1; k >= (long)0; k -= (long)1)
                {
                    long num = length * j + k + (long)1;
                    numArray1 = Arrays.Xor(numArray1, num);
                    byte[] numArray3 = AesKeyWrap.AesDec(kek, Arrays.Concat(new byte[][] { numArray1, numArray2[checked (k)] }));
                    numArray1 = Arrays.FirstHalf(numArray3);
                    numArray2[checked (k)] = Arrays.SecondHalf(numArray3);
                }
            }
            if (!Arrays.ConstantTimeEquals(AesKeyWrap.DefaultIV, numArray1))
            {
                throw new IntegrityException("AesKeyWrap integrity check failed.");
            }
            return(Arrays.Concat(numArray2));
        }
 public byte[][] Encrypt(byte[] aad, byte[] plainText, byte[] cek)
 {
     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);
     byte[] numArray2 = Arrays.Random(128);
     try
     {
         using (Aes ae = Aes.Create())
         {
             ae.Key = numArray1;
             ae.IV  = numArray2;
             using (MemoryStream memoryStream = new MemoryStream())
             {
                 using (ICryptoTransform cryptoTransform = ae.CreateEncryptor(ae.Key, ae.IV))
                 {
                     using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
                     {
                         cryptoStream.Write(plainText, 0, (int)plainText.Length);
                         cryptoStream.FlushFinalBlock();
                         array = memoryStream.ToArray();
                     }
                 }
             }
         }
     }
     catch (CryptographicException cryptographicException)
     {
         throw new EncryptionException("Unable to encrypt content.", cryptographicException);
     }
     byte[] numArray3 = this.ComputeAuthTag(aad, numArray2, array, numArray);
     return(new byte[][] { numArray2, array, numArray3 });
 }
        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;
                    aes.Mode    = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;

                    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);
            }
        }
        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;
                    aes.Mode    = CipherMode.CBC;
                    aes.Padding = PaddingMode.PKCS7;

                    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 #7
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);
 }