我正在尝试使用AES解密C#中的字符串:
public static string AesDecrypt(byte[] cipherText, byte[] Key, byte[] IV)
{
string plaintext = null;
// Create an Aes object with the specified key and IV
using Aes aesAlg = Aes.Create();
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decryptor to perform the stream transform
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// 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;
}
编码的数据是JSON,但是当我解密它时,我得到了所有正确的数据,只是缺少JSON内容的结尾}
。
我认为AES本身不是我的问题。我对
有疑问plaintext = srDecrypt.ReadToEnd();
因为仅缺少最后一个字符。
我不知道是否应该显式刷新任何流,但是无论如何这是一个非常奇怪的问题。
这是加密的完整代码:
public static string AesEncrypt(string plainText, byte[] Key, byte[] IV)
{
// Create an Aes object with the specified key and IV
using Aes aesAlg = Aes.Create();
aesAlg.Padding = PaddingMode.Zeros;
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create an encryptor to perform the stream transform
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// 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);
swEncrypt.Flush();
return Convert.ToBase64String(msEncrypt.ToArray());
}
这就是我所说的解密方法:
public static AuthenticationData ParseAuthenticationToken(string token)
{
byte[] tokenBytes = Convert.FromBase64String(token);
string json = AesEncryption.AesDecrypt(tokenBytes, aes.Key, aes.IV);
return JsonConvert.DeserializeObject<AuthenticationData>(json);
}
问题出在您的加密代码中。尽管您正在呼叫seEncrypt.Flush()
,但您并未呼叫csEncrypt.FlushFinalBlock()
。当流被丢弃时,这会自动发生,但是直到调用msEncrypt.ToArray()
之后,您才这样做。我会将代码重写为:
MemoryStream msEncrypt = new MemoryStream();
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using StreamWriter swEncrypt = new StreamWriter(csEncrypt);
swEncrypt.Write(plainText);
// swEncrypt is disposed here, flushing it. Then csEncrypt is disposed,
// flushing the final block.
}
return msEncrypt.ToArray();
我无法真正在此处跟踪您的代码,但这对我有用。
public static byte[] AesEncrypt(string plainText, byte[] Key, byte[] IV)
{
using var aes = Aes.Create();
aes.Padding = PaddingMode.Zeros;
var encryptor = aes.CreateEncryptor(Key, IV);
using var mstream = new MemoryStream();
using var cstream = new CryptoStream(mstream, encryptor, CryptoStreamMode.Write);
using var swriter = new StreamWriter(cstream);
swriter.Write(Convert.ToBase64String(Encoding.ASCII.GetBytes(plainText)));
swriter.Flush();
return mstream.ToArray();
}
public static string AesDecrypt(byte[] cipherText, byte[] Key, byte[] IV)
{
using var aes = Aes.Create();
aes.Padding = PaddingMode.Zeros;
var decryptor = aes.CreateDecryptor(Key, IV);
using var mstream = new MemoryStream(cipherText);
using var cdecrypt = new CryptoStream(mstream, decryptor, CryptoStreamMode.Read);
using var sreader = new StreamReader(cdecrypt);
return Encoding.ASCII.GetString(Convert.FromBase64String(sreader.ReadToEnd()));
}