C# 带Bouncycastle加密的AES CTR模式
我正在尝试使用实现AES CTR加密,使用。NET提供但不支持AES的CTR模式,因此选择Bouncycastle 我没能正确地编码,问题似乎出在IV上C# 带Bouncycastle加密的AES CTR模式,c#,cryptography,aes,bouncycastle,rijndaelmanaged,C#,Cryptography,Aes,Bouncycastle,Rijndaelmanaged,我正在尝试使用实现AES CTR加密,使用。NET提供但不支持AES的CTR模式,因此选择Bouncycastle 我没能正确地编码,问题似乎出在IV上 public string BytesToHex(byte[] bytes) { char[] c = new char[bytes.Length * 2]; byte b; for (int bx = 0, cx = 0; bx < bytes.Length; ++bx
public string BytesToHex(byte[] bytes)
{
char[] c = new char[bytes.Length * 2];
byte b;
for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
{
b = ((byte)(bytes[bx] >> 4));
c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
b = ((byte)(bytes[bx] & 0x0F));
c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
}
return new string(c);
}
public byte[] HexToBytes(string str)
{
if (str.Length == 0 || str.Length % 2 != 0)
return new byte[0];
byte[] buffer = new byte[str.Length / 2];
char c;
for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
{
// Convert first half of byte
c = str[sx];
buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);
// Convert second half of byte
c = str[++sx];
buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
}
return buffer;
}
private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
{
int minSize = cipher.GetOutputSize(data.Length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.ProcessBytes(data, 0, data.Length, outBuf, 0);
int length2 = cipher.DoFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
Array.Copy(outBuf,result,actualLength);
//System.arraycopy(outBuf, 0, result, 0, result.length);
return result;
}
private static byte[] decryptCTR(byte[] cipher, byte[] key, byte[] iv)
{
//Org.BouncyCastle.Crypto.Modes.SicBlockCipher
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new SicBlockCipher(new AesEngine()));
ParametersWithIV ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.Init(false, ivAndKey);
return cipherData(aes, cipher);
}
private static byte[] encryptCTR(byte[] plain, byte[] key, byte[] iv)
{
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new SicBlockCipher(
new AesEngine()));
ParametersWithIV ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.Init(true, ivAndKey);
return cipherData(aes, plain);
}
每次运行此命令时,我都会收到错误消息
解密中的最后一个块未完成
错误
谁能帮我一下吗。你根本不需要使用
填充缓冲块密码。计数器模式加密是分组密码的流模式。流式密码不需要填充
您可以使用BufferedBlockCipher
访问流媒体模式,因为SicBlockCipher
一次只允许您加密一个块。如果您只需要CTR模式,您可以轻松地自己编码-只需编写IV、IV+1、IV+2、IV+3。。。要缓冲(最多输入数据大小),请加密此缓冲区,并使用需要加密或解密的缓冲区进行xoring。
这可以通过内置Rijndael Managed实现。owlstead关于不需要填充的说法是正确的。我建议使用CipherUtilities.GetCipher(“AES/CTR/NoPadding”)来获取cipher对象,至少在基本正常工作之前是这样。您可能也会发现Org.BouncyCastle.Utilities.Encoders.Hex类很有用。试试看,SicBlockCipher的C#实现似乎只提供ProcessBlock,没有processbytes。@Sentinel谢谢,修复了。不过,我还是很快问了这个问题,因为我一直在努力理解C#端口的java代码是如何工作的。。。。Java中的SicBlockCipher似乎允许将单个字节直接处理到输出缓冲区,但BufferedBlockCipher在不调用DoFinal的情况下似乎无法做到这一点。我的理解正确吗?如果你愿意的话,我可以把这个问题变成一个SO问题。请创建一个问题,它对其他人似乎也很有用!好的,在这里添加了任何帮助,非常感谢。
private void btnDecryptDirectly_Click(object sender, EventArgs e)
{
String encodedMsgHex = "770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa0e311bde9d4e01726d3184c34451";
String key = "36f18357be4dbd77f050515c73fcf9f2";
byte [] keyBytes = HexToBytes(key);
byte[] cipher = HexToBytes(encodedMsgHex);
txtDecryptedText = BytesToHex(decryptCTR(cipher, keyBytes, IV));
rtbDecrypted.Text = txtDecryptedText;
}