请建议我在哪里需要更新/重构代码以消除异常。当我尝试使用以下代码解密加密的字符串时出现异常。
下一行抛出异常
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
public string EncryptAuthenticationTokenAes(string plainText)
{
byte[] encrypted;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
aesAlg.Padding = PaddingMode.None;
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return Convert.ToBase64String(encrypted);
}
public string DecryptPasswordAes(string encryptedString)
{
//Convert cipher text back to byte array
byte[] cipherText = Convert.FromBase64String(encryptedString);
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
aesAlg.Padding = PaddingMode.None;
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
使用 CryptoStream 时的标准错误,您忘记强制它加密流的最后字节。它将字节保存在内部缓冲区中,直到有足够的字节到达发出一个块。您必须强制输出最后几个字节。修正:
using (var msEncrypt = new MemoryStream())
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt)) {
swEncrypt.Write(plainText);
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
}
解密时出现异常,因为 encrypted 缺少最后的填充。真正的问题是由 using 语句引起的,如果您等到 CryptoStream 关闭后再获取加密字节,就不会出现此问题。但这效果不佳,因为 StreamWriter 上的 using 语句还会关闭 CryptoStream 和 MemoryStream。明确使用 FlushFinalBlock() 是最好的解决方法。
swEncrypt.Write(plainText);
swEncrypt.Flush();
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
在
swEncrypt.Flush()
之前调用csEncrypt.FlushFinalBlock()
解决了我的问题。