经过多年的工作,AesManaged开始产生空字符串加密结果 [英] AesManaged started to produce null string encryption result after years of working perfectly
问题描述
public static string Encrypt(string s,byte [] key,byte [] iv)
{
byte [] enc;
使用(AesManaged aes = new AesManaged())
{
ICryptoTransform ict = aes.CreateEncryptor(key,iv);
使用(MemoryStream ms = new MemoryStream())
使用(CryptoStream cs = new CryptoStream(ms,ict,CryptoStreamMode.Write))
使用(StreamWriter sw = new StreamWriter (cs))
{
sw.Write(s); enc = ms.ToArray();
}
}
return Convert.ToBase64String(enc);
}
public static string Decrypt(string p,byte [] key,byte [] iv)
{
string s = null;
使用(AesManaged aes = new AesManaged())
{
ICryptoTransform ict = aes.CreateDecryptor(key,iv);
使用(MemoryStream ms = new MemoryStream(Convert.FromBase64String(p)))
使用(CryptoStream cs = new CryptoStream(ms,ict,CryptoStreamMode.Read))
使用(StreamReader sr = new StreamReader(cs))
{
s = sr.ReadToEnd();
}
}
return s;
}
这些方法在这段时间内完美运行..直到昨天,当Encrypt生成null结果在一个有效的字符串。更改键
和 iv
没有任何区别。尝试在几台机器上执行 - 相同的结果。没有例外被抛出。但是,解密仍然正常!
为什么 Encrypt()
突然失败?有没有一些Windows Update更改了播放栏?
在找到并研究了几个类似的问题后(解密器提供空字符串; 在.NET中使用AES加密 - CryptographicException说填充无效,无法删除; 填充无效,无法删除,使用AesManaged ; 填充无效,无法删除使用AesManagedC#解密字符串时的异常),并再次查看我的代码,我注意到与MSDN示例的区别。事实上,我做了一个优化和,就是那个打破了执行!代码必须以这种方式拼写:
public static string Encrypt(string s,byte [] key,byte [] iv)
{
byte [] enc;
使用(AesManaged aes = new AesManaged())
{
ICryptoTransform ict = aes.CreateEncryptor(key,iv);
使用(MemoryStream ms = new MemoryStream())
{
using(CryptoStream cs = new CryptoStream(ms,ict,CryptoStreamMode.Write))
{
使用(StreamWriter sw = new StreamWriter(cs))
{
sw.Write(s);
}
}
enc = ms.ToArray();
}
}
return Convert.ToBase64String(enc);
}
请注意,每个使用( ..)
!是的,这意味着CryptoStream在我尝试使用缓冲区之前已经关闭了,因此被刷新了,使得这种方法安全。
不知道,为什么通过 @GregS 和 @HansPassant 没有这样做,但由于代码现在工作(恢复到原始版本:),我的问题是关闭的。感谢上帝的版本控制! :))
谢谢各位指导我解决!
A few years ago I wrote a simple wrapper based on MSDN - AesManaged Class code, to obscure values saved in registry (simply to prevent manual tampering with these, nothing more):
public static string Encrypt( string s, byte[] key, byte[] iv )
{
byte[] enc;
using( AesManaged aes = new AesManaged( ) )
{
ICryptoTransform ict = aes.CreateEncryptor( key, iv );
using( MemoryStream ms= new MemoryStream( ) )
using( CryptoStream cs= new CryptoStream( ms, ict, CryptoStreamMode.Write ) )
using( StreamWriter sw= new StreamWriter( cs ) )
{
sw.Write( s ); enc = ms.ToArray( );
}
}
return Convert.ToBase64String( enc );
}
public static string Decrypt( string p, byte[] key, byte[] iv )
{
string s= null;
using( AesManaged aes = new AesManaged( ) )
{
ICryptoTransform ict = aes.CreateDecryptor( key, iv );
using( MemoryStream ms= new MemoryStream( Convert.FromBase64String( p ) ) )
using( CryptoStream cs= new CryptoStream( ms, ict, CryptoStreamMode.Read ) )
using( StreamReader sr= new StreamReader( cs ) )
{
s= sr.ReadToEnd( );
}
}
return s;
}
These methods worked perfectly all this time .. until yesterday, when Encrypt produced a null result on a valid string. Changing key
and iv
does not make any difference. Tried executing on several machines - same result. No exceptions are thrown. However, decryption still works fine!
Why does Encrypt( )
suddenly fail? Is there some Windows Update that changed the play-field?
After finding and studying several similar questions (Aes decryptor gives empty string; Using AES encryption in .NET - CryptographicException saying the padding is invalid and cannot be removed; "Padding is invalid and cannot be removed" using AesManaged; Padding is invalid and cannot be removed Exception while decrypting string using "AesManaged" C#) and looking at my code again, I noticed the difference with MSDN sample. Indeed, i made an optimization and that is, what broke the execution! The code must be spelled this way:
public static string Encrypt( string s, byte[] key, byte[] iv )
{
byte[] enc;
using( AesManaged aes = new AesManaged( ) )
{
ICryptoTransform ict = aes.CreateEncryptor( key, iv );
using( MemoryStream ms= new MemoryStream( ) )
{
using( CryptoStream cs= new CryptoStream( ms, ict, CryptoStreamMode.Write ) )
{
using( StreamWriter sw= new StreamWriter( cs ) )
{
sw.Write( s );
}
}
enc = ms.ToArray( );
}
}
return Convert.ToBase64String( enc );
}
Notice the presence of curly braces after each using(..)
! Yes, that means the CryptoStream is closed - and therefore flushed - before i attempt to use the buffer, making this approach safe.
No idea, why solution by @GregS and @HansPassant did not do it, but since the code works now (reverted to original version :), my issue is closed. Thank god for version control! :))
Thank you guys for guiding me to the solution!
这篇关于经过多年的工作,AesManaged开始产生空字符串加密结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!