经过多年的工作,AesManaged开始产生空字符串加密结果 [英] AesManaged started to produce null string encryption result after years of working perfectly

查看:113
本文介绍了经过多年的工作,AesManaged开始产生空字符串加密结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几年前,我写了一个简单的包装器,基于 MSDN - AesManaged Class 代码,以掩盖在注册表中保存的值(只是为了防止手动篡改这些,没有更多):

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆