Rijndael解密返回奇怪的输出

时间:2016-03-15 09:17:49

标签: c#

我使用Rijndael算法进行加密和解密。

当我使用加密时,解密工作正常。

但是当我尝试单独使用Decryption时,它会返回类似这样的内容

  

JM“ec4ħdB̵Dq@ W上。

此外,我使用了两个按钮,一个用于加密,另一个用于解密,并在按钮点击时调用方法。

我无法理解为什么输出会像这样返回。即使我对这两种方法都使用相同的转换(UTF8编码)。

请帮我解决这个问题。

以下是我的代码:

public partial class Form1 : Form
{
    private RijndaelManaged myRijndael = new RijndaelManaged();
    private int iterations;
    private byte [] salt;

    public Form1(string strPassword)
    {
        myRijndael.BlockSize = 128;
        myRijndael.KeySize = 128;
        myRijndael.IV = HexStringToByteArray("e84ad660c4721ae0e84ad660c4721ae0");

        myRijndael.Padding = PaddingMode.PKCS7;
        myRijndael.Mode = CipherMode.CBC;
        iterations = 1000;
        salt = System.Text.Encoding.UTF8.GetBytes("cryptography123example");
        myRijndael.Key = GenerateKey(strPassword);
    }

    public string Encrypt(string strPlainText)
    {
        byte[] strText = new System.Text.UTF8Encoding().GetBytes(strPlainText);
        MemoryStream ms = new MemoryStream();
        ICryptoTransform transform = myRijndael.CreateEncryptor();
        CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write); 
        cs.Write(strText, 0, strText.Length);

        cs.FlushFinalBlock();
        return Convert.ToBase64String(ms.ToArray());
    }

    public string Decrypt(string encryptedText)
    {
        var encryptedBytes = Convert.FromBase64String(encryptedText);
        MemoryStream ms = new MemoryStream();
        ICryptoTransform transform = myRijndael.CreateDecryptor();
        CryptoStream cs = new CryptoStream(ms, transform, CryptoStreamMode.Write);
        cs.Write(encryptedBytes, 0, encryptedBytes.Length);

        return System.Text.Encoding.UTF8.GetString(ms.ToArray());
    }

    public static byte[] HexStringToByteArray(string strHex)
    {
        dynamic r = new byte[strHex.Length / 2];
        for (int i = 0; i <= strHex.Length - 1; i += 2)
        {
            r[i / 2] = Convert.ToByte(Convert.ToInt32(strHex.Substring(i, 2), 16));
        }
        return r;
    }

    private byte[] GenerateKey(string strPassword)
    {
        Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(System.Text.Encoding.UTF8.GetBytes(strPassword), salt, iterations);
        return rfc2898.GetBytes(128 / 8);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        EncryptOutput.Text = Encrypt(EncryptInput.Text);
    }

    private void button2_Click(object sender, EventArgs e)
    {
        DecryptOutput.Text = Decrypt(DecryptInput.Text);
    }
}

2 个答案:

答案 0 :(得分:1)

试试这段代码:

public string Encrypt(string strPlainText) {
    byte[] strText = System.Text.Encoding.UTF8.GetBytes(strPlainText);

    using (ICryptoTransform encryptor = myRijndael.CreateEncryptor())
    using (MemoryStream input = new MemoryStream(strText))
    using (MemoryStream output = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(output, encryptor, CryptoStreamMode.Write)) {
        input.CopyTo(cs);
        cs.FlushFinalBlock();
        return Convert.ToBase64String(output.GetBuffer(), 0, (int)output.Length);
    }
}

public string Decrypt(string encryptedText) {
    byte[] encryptedBytes = Convert.FromBase64String(encryptedText);

    using (ICryptoTransform decryptor = myRijndael.CreateDecryptor())
    using (MemoryStream input = new MemoryStream(encryptedBytes))
    using (MemoryStream output = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(input, decryptor, CryptoStreamMode.Read)) {
        cs.CopyTo(output);
        return System.Text.Encoding.UTF8.GetString(output.GetBuffer(), 0, (int)output.Length);
    }
}

public static byte[] HexStringToByteArray(string strHex) {
    var r = new byte[strHex.Length / 2];

    for (int i = 0; i < strHex.Length; i += 2) {
        r[i / 2] = byte.Parse(strHex.Substring(i, 2), NumberStyles.HexNumber);
    }
    return r;
}

请记住使用using模式...... dynamic只能在非常特殊的情况下使用。

请注意,Encrypt可以少一个Stream,与您编写的方式非常相似:

public string Encrypt(string strPlainText) {
    byte[] strText = System.Text.Encoding.UTF8.GetBytes(strPlainText);

    using (ICryptoTransform encryptor = myRijndael.CreateEncryptor())
    using (MemoryStream output = new MemoryStream())
    using (CryptoStream cs = new CryptoStream(output, encryptor, CryptoStreamMode.Write)) {
        cs.Write(strText, 0, strText.Length);
        cs.FlushFinalBlock();
        return Convert.ToBase64String(output.GetBuffer(), 0, (int)output.Length);
    }
}

Decrypt需要两个Stream,因为CryptoStream需要Stream作为参数,包含加密数据,并且更容易编写其输出(其中你不知道确切的lenth,感谢填充)到另一个流。

答案 1 :(得分:0)

cs.FlushFinalBlock();忘记在Decrypt()?一旦我修复了

,我就用你的代码对测试字符串进行了一次遍历