问题
I currently set up RijndaelManaged this way (the IV and Key are the same due to how the server handles the encryption). The server also uses CFB8 for the Mode, did I set this up correctly?
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;
}
I write data by doing this: ICryptoTransform e = GenerateAES(key).CreateEncryptor();
using(CryptoStream stream = new CryptoStream(BaseStream, e, CryptoStreamMode.Write))
{
stream.WriteByte(b);
stream.FlushFinalBlock();
}
BaseStream is a NetworkStream that I opened, and 'b' is a value that I sent to my function.
When I try to a 0x00 (as a test) to the stream, I get this error:
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()
I only made this function test whether or not that if I can communicate to the server without relying on any external libraries.
回答1:
You've set the PaddingMode
to None, and are trying to encrypt fewer bytes than a full block of data. Either encrypt more data (a multiple of the cipher.BlockSize
) or set the padding mode to something other than None so that it's automatically padded to the appropriate length.
Edit:
The default FeedbackSize for RijndaelManaged is 128 bits, but you want to use CFB8. If you set the cipher.FeedbackSize
to 8, you will be able to use it as a stream cipher with no padding, and every byte written to the CryptoStream will be encrypted and written to the output stream immediately. You should not call FlushFinalBlock
after each write, as this terminates the encryption process.
回答2:
Provided a solution here: https://stackoverflow.com/a/29038974/725903
The idea is to wrap ICryptoTransform passed to a CryptoStream ctor that handles TransformFinalBlock adding required bytes before encryption/decryption and removing them on return
来源:https://stackoverflow.com/questions/11776227/c-sharp-aes-128-cfb-error