1

到目前为止,我发现的很多项目都有些模糊或……不具体,所以我希望能得到答案。

我有两个小方法 - 看起来像这样的简单方法......

    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 只是返回 Encoding.UTF8.GetBytes(toByte); 我的测试字符串很简单——“SomethingToEncrypt”。我已经陷入困境,发现这种想法可能是问题(Convert.ToBase64String 和 Convert.FromBase64String),似乎没有任何区别。至于错误...

TestCase 'Tests.Encryption.EncryptionUnitTests.JustTestingThisOut' 失败:System.Security.Cryptography.CryptographicException:要解密的数据长度无效。在 System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(字节 [] inputBuffer,Int32 inputOffset,Int32 inputCount)

我有 FlushFinalBlock() 在那里,我认为可以这样做,但是......不,也没有区别。有任何想法吗?要尝试的东西?

4

3 回答 3

0

加密时,您首先写入data,然后用 astream包装并再次写入,这次使用加密。为什么?解密失败是因为它首先遇到的是未加密的数据。streamCryptoStreamdata

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

此外,您正在使用初始化向量作为密码。它们绝对不是一回事,像这样使用它会损害安全性。

于 2009-11-04T16:30:40.173 回答
0

我看不出这将如何像 jeriley 建议的那样工作,因为在你做的解密功能中

var encrypted = textToDecrypt.ToByteArray();

这里 textToDecrypt 是一个 base64 字符串。您首先必须将 base64 转换回普通字节,然后您可以使用它来解密。

于 2009-11-04T19:11:24.297 回答
0

您的代码中潜伏着一个间歇性错误...

您永远不应该将任何 System.Text.Encoding 类用于密文。您遇到间歇性错误。您应该使用 Base64 编码和 System.Convert 类方法。

  1. 要从加密的 byte[] 中获取加密的字符串,您应该使用:

Convert.ToBase64String(byte[] bytes)

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

Convert.FromBase64String(string data)

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

有关更多信息,请参阅 MS 安全大师 Shawn Fanning 在http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx上的帖子

于 2011-12-30T18:56:13.927 回答