如何解决我可以在.NET的CTR模式下使用AES吗?
| .NET的AES不能直接实现CTR。它仅实现CBC,CFB,CTS,ECB和OFB。 我可以使用其中任何一种模式并围绕它们安全地实现CTR,还是需要完全使用其他库?解决方法
是的,您可以使用.NET \的AES在ECB模式下构建一个CTR,并为每个加密的块自己创建和递增一个计数器。
WinZipAes加密流就是一个示例,它是开源DotNetZip的一部分。
WinZip指定在CTR模式下使用AES对加密的ZIP文件使用AES加密。 DotNetZip使用ECB和计数器实现CTR模式。
看到这里一些评论。
, 您需要做的就是在ECB模式下使用带有密钥(无填充,无IV)的AES加密128位计数器。然后,将纯文本与计数器的加密输出进行异或。对于每个块,计数器都会递增。由于XOR运算符的属性,加密和解密相同。
您可以在这里找到AES128 CTR模式的实现(我自己的):
https://gist.github.com/hanswolff/8809275
它应该易于使用。
, 基于@quadfinity的代码的紧凑型独立实现。
(尽管在原始代码中对类进行了命名)它可以使用任何密钥大小:128、192和256。只需提供正确大小的“ 0”即可。 “ 1”必须具有128位(16字节)。
该方法适用于加密和解密。
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,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));
}
}
另请参阅代码的PowerShell版本。
, Bouncy Castle的对称加密实现似乎支持CTR:
对称密钥算法:AES,河豚,山茶,CAST5,CAST6,DESede,DES,GOST28147,HC-128,HC-256,IDEA,NaccacheStern,RC2,RC4,RC5-32,RC5-64,RC6,Rijndael,Serpent, Skipjack,TEA / XTEA,Twofish和VMPC。
对称密钥模式:CBC,CFB,CTS,GOFB,OFB,OpenPGPCFB和SIC(也称为CTR)。
http://www.bouncycastle.org/csharp/
, 使用AES / CTR / NoPadding算法进行加密和解密,并使用全零,16字节初始化向量(IV)和使用加密安全生成器的一次性256位AES解密密钥。
使用@martin代码中的AesCtrTransform方法,我有以下用法示例。
请注意,我在此处将初始化向量(IV)字节数组留空,但是如果您想使事情更安全,则应填充它(了解更多:重用IV是否安全),但是随后必须存储IV以及钥匙。
const string text = \"Hello world\";
var key = new byte[32];
var initializationVector = new byte[16];
using (var random = new RNGCryptoServiceProvider())
{
random.GetNonZeroBytes(key);
}
string output;
string outputEncrypted;
using (var outputEncryptedStream = new MemoryStream())
{
using (var inputStream = new MemoryStream(Encoding.UTF8.GetBytes(text)))
{
AesCtrTransform(key,initializationVector,inputStream,outputEncryptedStream);
}
outputEncryptedStream.Position = 0;
using (var reader = new StreamReader(outputEncryptedStream,Encoding.UTF8,true,1024,true))
{
outputEncrypted = reader.ReadToEnd();
}
outputEncryptedStream.Position = 0;
using (var outputDecryptedStream = new MemoryStream())
{
AesCtrTransform(key,outputEncryptedStream,outputDecryptedStream);
outputDecryptedStream.Position = 0;
using (var reader = new StreamReader(outputDecryptedStream))
{
output = reader.ReadToEnd();
}
}
}
Assert.IsTrue(!string.IsNullOrEmpty(outputEncrypted));
Assert.AreEqual(text,output);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。