Solución:
Sí, puede crear un CTR utilizando el AES de .NET en modo ECB y un contador, que usted mismo inicializa e incrementa, para cada bloque cifrado.
Un ejemplo de esto es el flujo de cifrado WinZipAes, que es parte del DotNetZip de código abierto.
WinZip especifica el uso de cifrado AES para archivos ZIP cifrados, utilizando AES en modo CTR. DotNetZip implementa el modo CTR usando ECB y el contador.
Vea aquí algunos comentarios.
Una implementación independiente compacta basada en el código de @quadfinity.
(A pesar de nombrar la clase en el código original) Puede funcionar con cualquier tamaño de clave: 128, 192 y 256. Solo proporcione un key
de un tamaño correcto. salt
debe tener 128 bits (16 bytes).
El método funciona tanto para el cifrado como para el descifrado.
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(
string.Format(
"Salt size must be same as block size (actual: {0}, expected: {1})",
salt.Length, 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));
}
}
Si desea cifrar o descifrar un archivo, utilice File.Open
por inputStream
y File.Create
Para el outputStream
:
AesCtrTransform(key, salt, File.Open("file.in"), File.Create("file.out"));
Consulte también la versión de PowerShell del código.
Todo lo que necesita hacer es usar AES en modo ECB con una clave (sin relleno, sin IV) para cifrar un contador de 128 bits. Luego, el texto sin formato se XOR con la salida encriptada del contador. Para cada bloque se incrementa el contador. El cifrado y el descifrado son iguales debido a las propiedades del operador XOR.
Puede encontrar una implementación (la mía) para el modo AES128 CTR aquí:
https://gist.github.com/hanswolff/8809275
Debería ser fácil de usar.