我目前以这种方式设置RijndaelManaged(由于服务器如何处理加密,IV和Key是相同的)。服务器还使用CFB8作为模式,我是否正确设置了它?
public static RijndaelManaged GenerateAES(byte[] key)
{
RijndaelManaged cipher = new RijndaelManaged();
cipher.Mode = CipherMode.CFB;
cipher.Padding = PaddingMode.None;
cipher.KeySize = 128;
cipher.Key = key;
cipher.IV = key;
return cipher;
}
我通过这样做来写数据: ICryptoTransform e = GenerateAES(key).CreateEncryptor();
using(CryptoStream stream = new CryptoStream(BaseStream, e, CryptoStreamMode.Write))
{
stream.WriteByte(b);
stream.FlushFinalBlock();
}
BaseStream是我打开的NetworkStream,'b'是我发送给我的函数的值。
当我尝试对流进行0x00(作为测试)时,我收到此错误:
System.Security.Cryptography.CryptographicException: Length of the data to encrypt is invalid.
at System.Security.Cryptography.RijndaelManagedTransform.EncryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
我只是测试了这个函数是否可以在不依赖任何外部库的情况下与服务器进行通信。
答案 0 :(得分:5)
您已将PaddingMode
设置为无,并且正在尝试加密比完整数据块更少的字节。加密更多数据(cipher.BlockSize
的倍数)或将填充模式设置为None以外的其他模式,以便自动填充到适当的长度。
修改强>
RijndaelManaged的默认FeedbackSize是128位,但您想使用CFB8。如果将cipher.FeedbackSize
设置为8,则可以将其用作没有填充的流密码,并且写入CryptoStream的每个字节都将被加密并立即写入输出流。每次写入后,不都应该调用FlushFinalBlock
,因为这会终止加密过程。
答案 1 :(得分:0)
在此提供解决方案: https://stackoverflow.com/a/29038974/725903
我们的想法是将ICryptoTransform传递给CryptoStream ctor,该ctor处理TransformFinalBlock,在加密/解密之前添加所需的字节,并在返回时删除它们