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