public void RoundTrip() { var aesCounterMode = new AesCounterMode(); byte[] iv = new byte[] { 0xa7, 0xc8, 0x77, 0x4c, 0x92, 0x32, 0x3d, 0x1d, 0x44, 0x81, 0x01, 0xaf, 0xd0, 0x82, 0xea, 0x17 }; byte[] plainText = new byte[] { 0x8a, 0x07, 0xd2, 0xe7, 0x46, 0x4a, 0x0e, 0x11, 0xc4, 0x12, 0x01, 0x13, 0xc1, 0x68, 0xf9, 0x89 }; byte[] key = new byte[] { 0xe9, 0xf9, 0x49, 0x75, 0x6b, 0x80, 0xca, 0x96, 0x79, 0xaf, 0x0e, 0xb6, 0xf1, 0x7c, 0x29, 0x57, 0x22, 0x5f, 0x67, 0x5b, 0x5e, 0xf6, 0x96, 0xe7, 0xab, 0x3e, 0x7f, 0x54, 0xfe, 0xc1, 0x65, 0x6c }; AesCryptoServiceProvider provider = new AesCryptoServiceProvider(); provider.Key = key; provider.Mode = CipherMode.ECB; var transform = provider.CreateEncryptor(); byte[] cipherText = new byte[16]; aesCounterMode.TransformBlock(iv, plainText, transform, 42, 3, cipherText); byte[] roundTripResult = new byte[16]; aesCounterMode.TransformBlock(iv, cipherText, transform, 42, 3, roundTripResult); CollectionAssert.AreEqual(plainText, roundTripResult); }
/// <inheritdoc /> public ReadOnlySpan <byte> TransformBlock(ReadOnlySpan <byte> block) { using var hmac = new HMACSHA256(macKey); var rv = new byte[block.Length + 32]; var inputBuffer = block.ToArray(); using var aes = new AesCounterMode(); using var enc = aes.CreateEncryptor(cryptoKey, Array.Empty <byte>()); var encrypted = enc.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length); var hash = hmac.ComputeHash(encrypted); hash.CopyTo(rv.AsSpan()); encrypted.CopyTo(rv.AsSpan(hash.Length)); return(rv); }
/// <inheritdoc /> public int UntransformBlock(ReadOnlySpan <byte> input, Span <byte> block) { using var hmac = new HMACSHA256(macKey); var hash = hmac.ComputeHash(input.Slice(32).ToArray()); if (!input.Slice(0, 32).SequenceEqual(hash)) { throw new IOException("Invalid MAC"); } using var aes = new AesCounterMode(); using var enc = aes.CreateDecryptor(cryptoKey, Array.Empty <byte>()); var dec = enc.TransformFinalBlock(input.Slice(32).ToArray(), 0, input.Length - 32); dec.CopyTo(block); return(dec.Length); }
public override void init(int mode, byte[] key, byte[] iv) { this.mode = mode; aes_ctr = new AesCounterMode(); //String pad="NoPadding"; byte[] tmp; int ivsize = getIVSize(); if (iv.Length > ivsize) { tmp = new byte[ivsize]; Array.Copy(iv, 0, tmp, 0, tmp.Length); iv = tmp; } int bsize = getBlockSize(); if (key.Length > bsize) { tmp = new byte[bsize]; Array.Copy(key, 0, tmp, 0, tmp.Length); key = tmp; } try { // SecretKeySpec keyspec=new SecretKeySpec(key, "AES"); // cipher=javax.crypto.Cipher.getInstance("AES/CBC/"+pad); // cipher.init((mode==ENCRYPT_MODE? // javax.crypto.Cipher.ENCRYPT_MODE: // javax.crypto.Cipher.DECRYPT_MODE), // keyspec, new IvParameterSpec(iv)); cipher = (mode == ENCRYPT_MODE? aes_ctr.CreateEncryptor(key, iv): aes_ctr.CreateDecryptor(key, iv)); } catch (Exception e) { Console.WriteLine(e); cipher = null; } }
private static SymmetricAlgorithm PrepareCipher(byte[] decodedKey, Cipher cipher, byte[] iv, Options options) { // Pad key out to KeyLength in bytes if its too short or trancuate if it is too long int KeyLengthInBytes = cipher.KeyLength / 8; if (decodedKey.Length < KeyLengthInBytes || decodedKey.Length > KeyLengthInBytes) { var resizedKey = new byte[KeyLengthInBytes]; Buffer.BlockCopy(decodedKey, 0, resizedKey, 0, Math.Min(decodedKey.Length, resizedKey.Length)); decodedKey = resizedKey; } var iVector = new byte[cipher.IVLength]; if (!ArrayUtils.IsNullOrEmpty(iv)) { var ivLength = iv.Length; if (ivLength != cipher.IVLength) { if (ivLength < cipher.IVLength) // Pad zeros { if ((options & Options.OPENSSL_DONT_ZERO_PAD_KEY) != 0 /* && !EVP_CIPHER_CTX_set_key_length(ivLength)*/) { // Warning: Key length cannot be set for the cipher method throw new CryptographicException(Resources.LibResources.openssl_cannot_set_iv_length); } PhpException.Throw(PhpError.E_WARNING, Resources.LibResources.openssl_short_iv, iv.Length.ToString(), cipher.IVLength.ToString()); } else if (ivLength > cipher.IVLength) // Trancuate { PhpException.Throw(PhpError.E_WARNING, Resources.LibResources.openssl_long_iv, iv.Length.ToString(), cipher.IVLength.ToString()); ivLength = cipher.IVLength; } } Buffer.BlockCopy(iv, 0, iVector, 0, ivLength); } SymmetricAlgorithm alg = null; switch (cipher.Type) { case CipherType.AES: if (cipher.Mode == SupportedCipherMode.CTR) { alg = new AesCounterMode(); } else { alg = new RijndaelManaged { Padding = PaddingMode.PKCS7, KeySize = cipher.KeyLength } }; break; case CipherType.DES: alg = DES.Create(); break; case CipherType.TripleDES: alg = TripleDES.Create(); break; } if (TryGetDotNetCipherMode(cipher.Mode, out var cipherMode)) { alg.Mode = cipherMode; } alg.Key = decodedKey; alg.IV = iVector; if ((options & Options.OPENSSL_ZERO_PADDING) == Options.OPENSSL_ZERO_PADDING) { alg.Padding = PaddingMode.None; } return(alg); }