代码之家  ›  专栏  ›  技术社区  ›  jeriley

ASP.NET Rijndael Decrypt-要解密的数据长度

  •  1
  • jeriley  · 技术社区  · 17 年前

    到目前为止,我发现很多东西都有点含糊不清,或者…不具体,所以我希望得到答案。

    我有两个小方法-看起来很简单的方法…

        private const string initVector = "1234567890123456";
        private const string SaltValue = "ThisIsMySaltValue";
        private const int KeySize = 256;
    
        public static string Encrypt(string textToEncrypt)
        {
            var rijndael = new RijndaelManaged {KeySize = KeySize};
            var salt = SaltValue.ToByteArray();
            var vector = initVector.ToByteArray();
    
            var rfcBytes = new Rfc2898DeriveBytes(vector, salt, 2);
            var key = rfcBytes.GetBytes(rijndael.KeySize/8);
    
            ICryptoTransform encrypt = rijndael.CreateEncryptor(key, vector);
    
            var stream = new MemoryStream();
            var data = Encoding.ASCII.GetBytes(textToEncrypt);
            stream.Write(data, 0, data.Length);
    
            var cryptoStream = new CryptoStream(stream, encrypt, CryptoStreamMode.Write);
            cryptoStream.Write(data, 0, data.Length);
            cryptoStream.FlushFinalBlock();
    
            cryptoStream.Close();
            return Convert.ToBase64String(stream.ToArray());
        }
    
    
        public static string Decrypt(string textToDecrypt)
        {
            var vector = initVector.ToByteArray();
            var salt = SaltValue.ToByteArray();
            var encrypted = textToDecrypt.ToByteArray();
    
            var rijndael = new RijndaelManaged {KeySize = KeySize};
    
            var rfcBytes = new Rfc2898DeriveBytes(vector, salt, 2);
            var key = rfcBytes.GetBytes(rijndael.KeySize/8);
    
            var decrypt = rijndael.CreateDecryptor(key, vector);
    
            var stream = new MemoryStream(encrypted);
            var cryptoStream = new CryptoStream(stream, decrypt, CryptoStreamMode.Read);
    
            byte[] plainBytes = new byte[textToDecrypt.Length];
    
            var decryptedLength = cryptoStream.Read(plainBytes, 0, plainBytes.Length);
    
            var plainText = Encoding.UTF8.GetString(plainBytes, 0, decryptedLength);
            return plainText;
        }
    

    单元测试看起来像这样…

        [Test]
        public void JustTestingThisOut()
        {
            var encryptMe = "SomethingToEncrypt";
            string result = encryptMe.ConvertToEncrypted();
            result.ShouldNotEqual(encryptMe);
            string backToReadAble = result.ConvertToDecrpted();
            backToReadAble.ShouldEqual(encryptMe);
        }
    

    tobytearray只做一个返回编码。utf8.getbytes(tobyte);我的测试字符串很简单-“somethingtoencrypt”。我到兔子洞里去寻找 this 认为这可能是一个问题(convert.tobase64string和convert.frombase64string),但似乎没有什么区别。至于错误…

    测试用例 'tests.encryption.encryptionunittests.justtestingthesiout' 失败: System.Security.Cryptography.Cryptographic例外 :要解密的数据长度为 无效。在 System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(字节[] 输入缓冲区,Int32输入缓冲区,Int32 输入计数)

    我把flushfinalblock()放在里面,我以为可以,但是……不,也没什么区别。有什么想法吗?要尝试的东西?

    3 回复  |  直到 13 年前
        1
  •  0
  •   erickson    17 年前

    加密时,首先要写 data 到 stream 然后包装 流动 用一个 CryptoStream 写 数据 再一次,这次是加密。为什么?解密失败,因为它遇到的第一件事是未加密的数据。

    打印密文的值 之前 base64编码来验证这一点。你应该看到明文后面跟着一堆gobbledgook,这就是密文。

    另外,您使用初始化向量作为密码。它们绝对不是同一个东西,像这样使用它会损害安全性。

        2
  •  0
  •   Henri    17 年前

    我看不出这会像Jeriley建议的那样工作,因为在解密函数中,你会这样做。

    var encrypted = textToDecrypt.ToByteArray();

    这里texttodecrypt是base64字符串。首先必须将base64转换回普通字节,然后才能使用这些字节进行解密。

        3
  •  0
  •   Nathan Baulch    14 年前

    你的代码中潜伏着一个间歇的错误…

    不能对密码文本使用任何System.Text.Encoding类。你 将 遇到间歇性错误。您应该使用base64编码和system.convert类方法。

    1. 要从加密字节[]获取加密字符串,应使用:

    Convert.ToBase64String(byte[] bytes)

    1. 要从要加密的字符串中获取原始字节[],应使用:

    Convert.FromBase64String(string data)

    另外一个注意事项是你需要 FlushFinalBlock() 在加密时,否则将无法正确填充。

    有关更多信息,请参阅安全专家Shawn Fanning女士在 http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx

    推荐文章