我正在尝试解密用 Rijndael 算法加密的字符串。如果密钥和 IV 的长度少于 16 个字符,这种类型的加密会在密钥和 IV 的右侧使用“#”填充。要解密的字符串是从将它和密钥以 XML SOAP 格式发送给我的 Web 服务接收的。IV 是我机器的 Mac 地址(服务器用作 IV 来加密字符串)。当我尝试解密收到的字符串时,我的程序在此指令处崩溃:
while ((num5 = stream3.ReadByte()) != -1)
它给了我这个错误“填充无效并且无法删除”。我在 MSDN 上搜索了这个错误,它说当用于加密的 IV 与用于解密的 IV 不同时会发生这种情况,但是,我再说一遍,IV 是 MacAddress 并且每次都相同。
这是加密和解密函数的源代码:
public static string Decrypt(string strInputString, string strKeyString, string myIV)
{
if ((strInputString == null) || (strInputString.Length == 0))
{
return strInputString;
}
try
{
int num5;
int keySize = 0x100;
int blockSize = 0x100;
int length = keySize / 0x10;
if (strKeyString.Length > length)
{
strKeyString = strKeyString.Substring(0, length);
}
if (strKeyString.Length < length)
{
strKeyString = strKeyString.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(strKeyString);
if (myIV.Length > length)
{
myIV = myIV.Substring(0, length);
}
if (myIV.Length < length)
{
myIV = myIV.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(myIV);
byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
RijndaelManaged managed = new RijndaelManaged {
BlockSize = blockSize,
KeySize = keySize
};
MemoryStream stream = new MemoryStream();
for (int i = 0; i < strInputString.Length; i += 2)
{
stream.WriteByte(byte.Parse(strInputString.Substring(i, 2), NumberStyles.AllowHexSpecifier));
}
stream.Position = 0L;
MemoryStream stream2 = new MemoryStream();
CryptoStream stream3 = new CryptoStream(stream, managed.CreateDecryptor(bytes, rgbIV), CryptoStreamMode.Read);
while ((num5 = stream3.ReadByte()) != -1)
{
stream2.WriteByte((byte) num5);
}
stream3.Close();
stream2.Close();
stream.Close();
byte[] buffer3 = stream2.ToArray();
return Encoding.Unicode.GetString(buffer3);
}
catch (Exception exception)
{
Log.Error(exception.Message);
}
}
public static string Encrypt(string strInputString, string strKeyString, string myIV)
{
if ((strInputString == null) || (strInputString.Length == 0))
{
return strInputString;
}
try
{
int num4;
int keySize = 0x100;
int blockSize = 0x100;
int length = keySize / 0x10;
if (strKeyString.Length > length)
{
strKeyString = strKeyString.Substring(0, length);
}
if (strKeyString.Length < length)
{
strKeyString = strKeyString.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(strKeyString);
if (myIV.Length > length)
{
myIV = myIV.Substring(0, length);
}
if (myIV.Length < length)
{
myIV = myIV.PadRight(length, '#');
}
Encoding.Unicode.GetBytes(myIV);
byte[] bytes = Encoding.Unicode.GetBytes(strKeyString);
byte[] rgbIV = Encoding.Unicode.GetBytes(myIV);
string str = "";
RijndaelManaged managed = new RijndaelManaged {
BlockSize = blockSize,
KeySize = keySize
};
MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(strInputString));
MemoryStream stream2 = new MemoryStream();
CryptoStream stream3 = new CryptoStream(stream2, managed.CreateEncryptor(bytes, rgbIV), CryptoStreamMode.Write);
while ((num4 = stream.ReadByte()) != -1)
{
stream3.WriteByte((byte) num4);
}
stream3.Close();
stream2.Close();
stream.Close();
foreach (byte num5 in stream2.ToArray())
{
str = str + num5.ToString("X2");
}
return str;
}
catch (Exception exception)
{
Log.Error(exception.Message);
}
}
}