.NET's AES does not implement CTR directly. It only implements CBC, CFB, CTS, ECB and OFB.
Can I use any of these modes and securely implement CTR around them, or do I need to use a different library altogether?
The way encryption works in AES CTR mode is that we generate some random bits with the encryption key provided and the IV. With these random bits we then XOR them with our string. This creates a randomized text.
XTS mode is the most common if you are encoding a random accessible data (like a hard disk or RAM). OCB is by far the best mode, as it allows encryption and authentication in a single pass.
Out of 128-bit, 192-bit, and 256-bit AES encryption, which progressively use more rounds of encryption for improved security, 128-bit AES encryption is technically the least secure.
The collision power attack is a typical physical attack to recover the secret key of the AES algorithm. However, almost all collision attacks aim at the detection of internal collisions caused by the output of S-boxes, and the linear layers are not concerned with those protected implementations.
A compact standalone implementation based on the code by @quadfinity.
(Despite naming of the class in the original code) It can work with any key size: 128, 192 and 256. Just provide a key
of a correct size. salt
must have 128 bits (16 bytes).
The method works both for encryption and decryption.
public static void AesCtrTransform( byte[] key, byte[] salt, Stream inputStream, Stream outputStream) { SymmetricAlgorithm aes = new AesManaged { Mode = CipherMode.ECB, Padding = PaddingMode.None }; int blockSize = aes.BlockSize / 8; if (salt.Length != blockSize) { throw new ArgumentException( "Salt size must be same as block size " + $"(actual: {salt.Length}, expected: {blockSize})"); } byte[] counter = (byte[])salt.Clone(); Queue<byte> xorMask = new Queue<byte>(); var zeroIv = new byte[blockSize]; ICryptoTransform counterEncryptor = aes.CreateEncryptor(key, zeroIv); int b; while ((b = inputStream.ReadByte()) != -1) { if (xorMask.Count == 0) { var counterModeBlock = new byte[blockSize]; counterEncryptor.TransformBlock( counter, 0, counter.Length, counterModeBlock, 0); for (var i2 = counter.Length - 1; i2 >= 0; i2--) { if (++counter[i2] != 0) { break; } } foreach (var b2 in counterModeBlock) { xorMask.Enqueue(b2); } } var mask = xorMask.Dequeue(); outputStream.WriteByte((byte)(((byte)b) ^ mask)); } }
If you want to encrypt or decrypt a file, use File.OpenRead
for inputStream
and File.Create
for the outputStream
:
using (Stream inputStream = File.OpenRead("file.in")) using (Stream outputStream = File.Create("file.out")) { AesCtrTransform(key, salt, inputStream, outputStream); }
See also PowerShell version of the code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With