尝试使用ICryptoTransform
在加密和解密期间重复使用AesCryptoServiceProvider
个对象时,会出现“错误”错误。通过将应用程序的.NET框架版本升级到4.6.2来解决此问题。
此堆栈溢出帖子(Reuse ICryptoTransform objects)和显示.net版本发行说明(https://github.com/Microsoft/dotnet/blob/master/Documentation/compatibility/aescryptoserviceprovider-decryptor-provides-a-reusable-transform.md)的microsoft github页面解释了此错误以及如何解决此问题。在大多数情况下,当我将我的应用程序升级到.NET版本4.6.2时,这似乎是预期的,对于ASP.NET应用程序有一点点问题 - 在其中一个堆栈溢出注释中提到了解决方案。
但是,在尝试为Azure云服务实现此修复时,所显示的行为就好像框架未更新,无论是否存在上下文切换或项目是否已升级到.NET 4.6.2。
ICryptoTransform
对象时,Decrypt
方法的字符串输出已损坏。注意我只使用本地模拟器对此进行了测试,并且还尝试了以下操作。
任何人都可以确认同样的行为吗?有关升级.NET框架的Azure云服务是否有特殊情况?也许我不知道某个app.config设置?
代码示例
private ICryptoTransform _decryptorTransform;
private ICryptoTransform DecryptorTransform
{
get
{
if (null == _decryptorTransform || !_decryptorTransform.CanReuseTransform)
{
_decryptorTransform?.Dispose();
using (var aes = GetNewCryptoProvider())
{
_decryptorTransform = aes.CreateDecryptor();
}
}
return _decryptorTransform;
}
}
public string Encrypt(string plainText, EncodingType type)
{
byte[] encrypted;
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, EncryptorTransform, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
string encryptedString = "";
if (type == EncodingType.Base32)
encryptedString = Base32.Encode(encrypted);
else if (type == EncodingType.Base64)
encryptedString = Convert.ToBase64String(encrypted);
else
throw new NotImplementedException();
if (_azureStorageSafe)
return encryptedString.Replace('/', '|').Replace('+', '-');
else
return encryptedString;
}
private AesCryptoServiceProvider GetNewCryptoProvider()
{
var aes = new AesCryptoServiceProvider();
aes.Key = keyBytes;
aes.IV = ivBytes;
aes.Padding = PaddingMode.Zeros;
aes.Mode = CipherMode.CBC;
return aes;
}