C#Bouncy Castle:AES CTR为什么';它不是自动递增的
我正在尝试在c#中实现AES 128 CTR加密。我发现Bouncy Castle非常有用。这是我的密码:C#Bouncy Castle:AES CTR为什么';它不是自动递增的,c#,cryptography,aes,bouncycastle,C#,Cryptography,Aes,Bouncycastle,我正在尝试在c#中实现AES 128 CTR加密。我发现Bouncy Castle非常有用。这是我的密码: public class AESCrypto { private byte[] Key = new byte[16]; private byte[] IV = new byte[16]; private const int CHUNK_SIZE = 16; private IBufferedCipher cipher = CipherUtilities.GetCip
public class AESCrypto
{
private byte[] Key = new byte[16];
private byte[] IV = new byte[16];
private const int CHUNK_SIZE = 16;
private IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CTR/NoPadding");
// Key and IV I get from client.
public AESCrypto(byte[] key, byte[] iv, bool forEncryption) {
Key = key;
IV = iv;
cipher.Init(forEncryption, new ParametersWithIV(new KeyParameter(Key), IV));
}
public byte[] PerformAES(byte[] incomingBytes)
{
int blockCount = incomingBytes.Length / CHUNK_SIZE; // Number of blocks
int blockRemaining = incomingBytes.Length % CHUNK_SIZE; // Remaining bytes of the last block
byte[] outcomingBytes = new byte[incomingBytes.Length];
for (var i = 0; i < blockCount; i++)
{
// Why do I need to re-init it again?
//cipher.Init(false, new ParametersWithIV(new KeyParameter(Key), IV));
byte[] temp = new byte[CHUNK_SIZE];
Array.Copy(incomingBytes, i * CHUNK_SIZE, temp, 0, CHUNK_SIZE);
byte[] decryptedChunk = cipher.ProcessBytes(temp);
Array.Copy(decryptedChunk, 0, outcomingBytes, i * CHUNK_SIZE, CHUNK_SIZE);
//Increase(IV); Why do I need to increse iv by hand?
}
if (blockRemaining != 0)
{
// Why do I need to re-init it again?
//cipher.Init(false, new ParametersWithIV(new KeyParameter(Key), IV));
byte[] temp = new byte[blockRemaining];
Array.Copy(incomingBytes, incomingBytes.Length - blockRemaining, temp, 0, blockRemaining);
byte[] decryptedChunk = cipher.DoFinal(temp);
Array.Copy(decryptedChunk, 0, outcomingBytes, incomingBytes.Length - blockRemaining, blockRemaining);
//Increase(IV); Why do I need to increse iv by hand?
}
return outcomingBytes;
}
private void Increase(byte[] iv)
{
for (var i = 0; i < iv.Length; i++)
{
iv[i]++;
if (iv[i] != 0)
{
break;
}
}
}
}
公共类AES加密
{
专用字节[]键=新字节[16];
专用字节[]IV=新字节[16];
私有常量int CHUNK_SIZE=16;
私有IBufferdCipher cipher=CipherUtilities.GetCipher(“AES/CTR/NoPadding”);
//我从客户那里拿到钥匙和IV。
公共AES加密(字节[]密钥,字节[]iv,布尔加密){
钥匙=钥匙;
IV=IV;
Init(forEncryption,新参数swithiv(newkeyparameter(Key),IV));
}
公共字节[]性能(字节[]输入字节)
{
int blockCount=incomingBytes.Length/CHUNK\u SIZE;//块数
int blockleveling=incomingBytes.Length%CHUNK\u SIZE;//最后一个块的剩余字节
byte[]outcomingBytes=新字节[incomingBytes.Length];
对于(变量i=0;i
乍一看,这段代码应该可以正常工作。但事实并非如此。注意注释掉的行:
//Init(false,新参数swithiv(新的KeyParameter(Key),IV));
和
//增加(四);为什么我需要手动增加iv?
只有在我取消注释它们时,我的代码才能正常工作
我想知道为什么我必须手动增加计数器?或者我在构造器的设置中出错了?我对Bouncy Castle不太熟悉
另外,我使用的是Nuget的BC 1.8.6.1版本。问题是为什么首先要进行缓冲(或者说,为什么需要这段代码)。您使用的是缓冲密码,对吗?只需执行多个
ProcessBytes
并始终执行一个DoFinal
,就可以了。别忘了一起讨论结果。尽管如此,我还是会投票支持你,因为这并不能解释原因。请注意,你没有在任何地方重置密码。每次加密都应该重新初始化密码。如果你把它当作一块地,这就不会发生。通常,只有键应该是字段。请注意,创建/初始化密码通常不会花费太多时间。我只使用了一次密码实例。所以,你是说,每次都需要重新初始化,而且这样做是正确的吗?是的,如果只是因为你想在每次运行时更新IV。通常情况下,IV(CTR模式下计数器的起点)是计数器值的前缀。在CTR模式的情况下,我会使用一个显式的nonce,然后用零填充其他最右边的字节(计数器是您实现的大端值)。当然,不需要包含零字节,您只需要存储nonce。您也可以在两侧使用计数器,但是更新nonce对于CTR来说是绝对重要的。如果没有它,你基本上就失去了所有的机密性。问题是为什么你首先要缓冲(或者说,为什么你需要这段代码)。您使用的是缓冲密码,对吗?只需执行多个ProcessBytes
并始终执行一个DoFinal
,就可以了。别忘了一起讨论结果。尽管如此,我还是会投票支持你,因为这并不能解释原因。请注意,你没有在任何地方重置密码。每次加密都应该重新初始化密码。如果你把它当作一块地,这就不会发生。通常,只有键应该是字段。请注意,创建/初始化密码通常不会花费太多时间。我只使用了一次密码实例。所以,你是说,每次都需要重新初始化,而且这样做是正确的吗?是的,如果只是因为你想在每次运行时更新IV。通常情况下,IV(CTR模式下计数器的起点)是计数器值的前缀。在CTR模式的情况下,我会使用一个显式的nonce,然后用零填充其他最右边的字节(计数器是您实现的大端值)。当然,不需要包含零字节,您只需要存储nonce。您也可以在两侧使用计数器,但是更新nonce对于CTR来说是绝对重要的。没有它,你基本上失去了所有的机密性。