我正在实现一个webservice客户端,它需要使用128位Rijndael来加密请求。因为Silverlight中不存在RijndaelManaged类,所以我遵循了下面的建议:AesManaged and RijndaelManaged
结果是我得到的结果是正确的(我的意思是,我使用RijndaelManaged得到的是相同的),只有前32个字符(128位),完全是块的大小。我不知道我到底做错了什么。我的.Net实现(RijndaelManaged)是这样的:
private static byte[] Encrypt(byte[] PlainTextBytes, byte[] KeyBytes, string InitialVector)
{
byte[] InitialVectorBytes = Encoding.UTF8.GetBytes(InitialVector);
RijndaelManaged SymmetricKey = new RijndaelManaged();
SymmetricKey.Mode = CipherMode.ECB;
SymmetricKey.Padding = PaddingMode.PKCS7;
SymmetricKey.BlockSize = 128;
ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);
MemoryStream MemStream = new MemoryStream();
CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
CryptoStream.FlushFinalBlock();
byte[] CipherTextBytes = MemStream.ToArray();
MemStream.Close();
CryptoStream.Close();
return CipherTextBytes;
}而我的Silverlight是:
private string Encrypt(byte[] PlainTextBytes, byte[] KeyBytes, string InitialVector)
{
AesManaged SymmetricKey = new AesManaged();
byte[] InitialVectorBytes = SymmetricKey.IV;
//NOTE- because Mode and Padding don't exist in AESManaged for Silverlight, I have to do the padding myself
//for an empty InitalVector (which is my case)
for (int i = 0; i < InitialVectorBytes.Length; i++) InitialVectorBytes[i] = 0;
SymmetricKey.BlockSize = 128;
ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes);
MemoryStream MemStream = new MemoryStream();
CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write);
CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
CryptoStream.FlushFinalBlock();
byte[] CipherTextBytes = MemStream.ToArray();
MemStream.Close();
CryptoStream.Close();
return CipherTextBytes;
}发布于 2011-03-19 01:21:19
还不清楚是否真的清除了IV,您只是将其作为字节数组获取,然后将其清除,但我不确定IV属性是否在返回之前复制了内部值。我会用这个:
SymmetricKey.BlockSize = 128;
SymmetricKey.IV = new byte[SymmetricKey.BlockSize / 8];(顺便说一句,我还会停止对参数和局部变量使用PascalCase。通常的约定是对非常数变量使用camelCase。)
编辑:示例代码来演示你的代码并没有真正改变IV:
AesManaged aes = new AesManaged();
byte[] iv = aes.IV;
iv[0] = 1;
iv[1] = 2;
Console.WriteLine(BitConverter.ToString(iv));
Console.WriteLine(BitConverter.ToString(aes.IV));示例输出:
01-02-01-1B-6E-05-B8-2A-C0-86-17-EF-A2-80-60-7B
D8-48-01-1B-6E-05-B8-2A-C0-86-17-EF-A2-80-60-7B换句话说,改变数组中的值实际上并不会改变IV。
发布于 2011-11-09 22:09:08
您的.NET版本使用EBC模式,而Silverlight版本使用CBC。第一个输出块在两个版本中是相同的,因为在ECB模式下不使用初始化向量,而在CBC模式下初始化向量为零。在CBC模式中,每个块与前一个块进行XORed (第一个块使用初始化向量进行XORed ),然后加密,而在EBC模式中,每个块按原样加密。
https://stackoverflow.com/questions/5355536
复制相似问题