【问题标题】:AES algorithm error in c#c#中的AES算法错误
【发布时间】:2016-04-22 09:57:23
【问题描述】:

我编写了一个使用 AES 算法加密和解密示例文本的代码。当我单击第一个按钮时,我想加密将显示在 textbox1 上的字符串,对于第二个按钮单击,解密后的值应显示在 textbox2 上。

代码如下:

public partial class _Default : Page
{
    public byte[] key = null; public byte[] iv = null; public byte[] bytesToEncrypt = null; public static byte[] encryptedBytes = null; public byte[] decryptedBytes = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        RijndaelManaged aesAlg = new RijndaelManaged();
        aesAlg.GenerateKey();
        aesAlg.GenerateIV();
        key = aesAlg.Key;
        iv = aesAlg.IV;
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        // original bytes
        bytesToEncrypt = new byte[TextBox2.Text.ToString().Length * sizeof(char)];

        encryptedBytes = CryptoAes.Encrypt(bytesToEncrypt, key, iv);
        TextBox1.Text = Convert.ToBase64String(encryptedBytes);

        byte[] bytesToEncrypt1 = new byte[TextBox2.Text.Length];
        decryptedBytes = CryptoAes.Decrypt(encryptedBytes, key, iv);//working here.       
    }

    protected void Button2_Click(object sender, EventArgs e)
    {
        var s = Convert.FromBase64String(TextBox1.Text);                    
        decryptedBytes = CryptoAes.Decrypt(encryptedBytes, key, iv);
        TextBox2.Text = System.Text.Encoding.Unicode.GetString(decryptedBytes);//not working
    }
}

internal sealed class CryptoAes
{
    public static byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
    {
        byte[] encryptedData = null;

        if (data == null)
            throw new ArgumentNullException("data");

        if (data == key)
            throw new ArgumentNullException("key");

        if (data == iv)
            throw new ArgumentNullException("iv");

        using (RijndaelManaged aesAlg = new RijndaelManaged())
        {
            aesAlg.Key = key;
            aesAlg.IV = iv;
            aesAlg.Padding = PaddingMode.Zeros;
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
            encryptedData = encryptor.TransformFinalBlock(data, 0, data.Length);
        }

        return encryptedData;
    }

    public static byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
    {
        byte[] decryptedData = null;

        if (data == null)
            throw new ArgumentNullException("data");

        if (data == key)
            throw new ArgumentNullException("key");

        if (data == iv)
            throw new ArgumentNullException("iv");

        using (RijndaelManaged aesAlg = new RijndaelManaged())
        {
            aesAlg.Key = key;
            aesAlg.IV = iv;
            aesAlg.Padding = PaddingMode.Zeros;
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
            decryptedData = decryptor.TransformFinalBlock(data, 0, data.Length);

        }

        return decryptedData;
    }
}

对于第一个按钮,单击解密工作正常。但是当我单击第二个按钮时,解密的文本会显示一些垃圾字符。

为了弄清楚这一点,我将 encryptedBytes 设为静态并在单击第二个按钮时重用它,但仍然是带有垃圾值的相同输出。我想知道当我单击第一个按钮时,相同的输入如何给出正确的输出。

谁能帮我解决这个问题?

【问题讨论】:

  • 所以,您有输入,有预期的输出,您也有代码。那么您期望我们提供什么帮助?有什么错误吗?
  • 两个按钮都是用来解密的? *“按钮点击解密工作正常”*
  • 第一个按钮点击,解密工作正常。问题在于第二个按钮单击。第一个按钮用于加密,第二个按钮用于解密。如果我也在第一个按钮中编写解密代码的逻辑,它工作正常。
  • 不会bytesToEncrypt 只是一个空数组?你想加密什么,TextBox2.Text 中的数据?
  • 它不是空数组。它有价值观。我检查了一切。但查不出有什么区别。请运行代码,您可以复制问题。

标签: c# encryption cryptography aes rijndael


【解决方案1】:

我有一个你正在尝试的工作代码看看

            internal const string Inputkey = "560A18CD-6346-4CF0-A2E8-671F9B6B9EA9";

            public static string EncryptRijndael(string text, string salt)
            {
                if (string.IsNullOrEmpty(text))
                    throw new ArgumentNullException("text");

                var aesAlg = NewRijndaelManaged(salt);

                var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
                var msEncrypt = new MemoryStream();
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                using (var swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(text);
                }

                return Convert.ToBase64String(msEncrypt.ToArray());
            }


            public static bool IsBase64String(string base64String)
            {
                base64String = base64String.Trim();
                return (base64String.Length % 4 == 0) &&
                       Regex.IsMatch(base64String, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);

            }


            public static string DecryptRijndael(string cipherText, string salt)
            {
                if (string.IsNullOrEmpty(cipherText))
                    throw new ArgumentNullException("cipherText");

                if (!IsBase64String(cipherText))
                    throw new Exception("The cipherText input parameter is not base64 encoded");

                string text;

                var aesAlg = NewRijndaelManaged(salt);
                var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                var cipher = Convert.FromBase64String(cipherText);

                using (var msDecrypt = new MemoryStream(cipher))
                {
                    using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (var srDecrypt = new StreamReader(csDecrypt))
                        {
                            text = srDecrypt.ReadToEnd();
                        }
                    }
                }
                return text;
            }

            private static RijndaelManaged NewRijndaelManaged(string salt)
            {
                if (salt == null) throw new ArgumentNullException("salt");
                var saltBytes = Encoding.ASCII.GetBytes(salt);
                var key = new Rfc2898DeriveBytes(Inputkey, saltBytes);

                var aesAlg = new RijndaelManaged();
                aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
                aesAlg.IV = key.GetBytes(aesAlg.BlockSize / 8);

                return aesAlg;
            }

            protected void Button1_Click(object sender, EventArgs e)
            {
                TextBox1.Text = EncryptRijndael(TextBox1.Text, Inputkey);
            }
            protected void Button2_Click(object sender, EventArgs e)
            {
                TextBox2.Text = DecryptRijndael(TextBox1.Text, Inputkey);
            }

希望对您有所帮助。

【讨论】:

  • 如何在此提及 keysize 和 blocksize?
【解决方案2】:

错误在您的第一行代码中:

// original bytes
bytesToEncrypt = new byte[TextBox2.Text.ToString().Length * sizeof(char)];

如果您检查bytesToEncrypt,您会发现它包含一个全为零的数组:

Name             Value            Type
bytesToEncrypt   byte[]           System.Byte[]
├── [0]          0                byte
├── [1]          0                byte
├── [2]          0                byte
├── [3]          0                byte
├── [4]          0                byte
├── [5]          0                byte
├── [7]          0                byte
├── [8]          0                byte
├── [9]          0                byte
├── [10]         0                byte
├── [11]         0                byte
└── [12]         0                byte

然后你加密所有的零。

当你解密它时,它会返回全零。

您可以在 C# Fiddle 上使用 here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多