Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use AES in CTR mode in .NET?

Tags:

.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?

like image 780
jnm2 Avatar asked Jun 16 '11 15:06

jnm2


People also ask

How does AES CTR mode work?

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.

What is the best mode for AES?

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.

Is AES 128 CTR secure?

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.

Can AES have collisions?

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.


1 Answers

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.

like image 169
Martin Prikryl Avatar answered Sep 18 '22 18:09

Martin Prikryl