如何解密Rijndael加密中超过16个字母的单词

时间:2016-08-27 08:08:57

标签: c# encryption rijndael

在youtube上观看视频后,我在C#中使用Rijndael制作了加密程序。这很简单。

Interface picture 我可以输入64位和128位密钥。但是不允许使用192位密钥(为什么?)。

如果我使用64位密钥,当我加密一个字并尝试解密它时,它只解密字符数为< = 16的字。它的字符数大于16,抛出的错误信息称“填充是无效且无法删除“。

128位密钥也是如此。只有具有字符数< = 32的字才被解密。否则会显示相同的错误消息。

以下是对问题进行清晰认识的总结

Problem Summery picture 这是加密的代码

// need using System.Security.Cryptography;
// using System.IO;
public Form1()
{
    InitializeComponent();
    desObj = Rijndael.Create();
}

string cipherData;
byte[] chipherbytes;
byte[] plainbyte;
byte[] plainbyte2;
byte[] plainkey;                

SymmetricAlgorithm desObj;

private void button2_Click(object sender, EventArgs e)
{

    try
    {

        cipherData = textBox1.Text;
        plainbyte = Encoding.ASCII.GetBytes(cipherData);
        plainkey = Encoding.ASCII.GetBytes(textBox4.Text);
        desObj.Key = plainkey;
        //choose any method 
        desObj.Mode = CipherMode.CBC;
        desObj.Padding = PaddingMode.PKCS7;
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, desObj.CreateEncryptor(), CryptoStreamMode.Write);
        cs.Write(plainbyte, 0, plainbyte.Length);
        cs.Close();
        chipherbytes = ms.ToArray();
        ms.Close();
        textBox2.Text = Encoding.ASCII.GetString(chipherbytes);
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

和解密代码是

private void button3_Click(object sender, EventArgs e)
{
    try
    {

        MemoryStream ms1 = new MemoryStream(chipherbytes);
        CryptoStream cs1 = new CryptoStream(ms1, desObj.CreateDecryptor(), CryptoStreamMode.Read);
        cs1.Read(chipherbytes, 0, chipherbytes.Length);
        plainbyte2 = ms1.ToArray();
        cs1.Close();
        ms1.Close();
        textBox3.Text = Encoding.ASCII.GetString(plainbyte2);       

    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

1 个答案:

答案 0 :(得分:0)

密文由任意字节组成,不必构成有效的ASCII编码。如果存在一些不可打印的ASCII字符,则以这种方式使用时不会打印它们:Encoding.ASCII.GetString(chipherbytes)

您需要使用Base64或Hex之类的密码对密文进行编码,这样可以使编码密文更大,但可以完美地表示为打印字符串。

其他考虑因素:

  • CBC模式需要初始化向量(IV),因为您没有设置任何IV,所以它将为您生成。问题是你在解密过程中需要相同的IV。此代码有效,因为您使用相同的desObj进行加密和解密,并且它包含相同的IV,但是当您开始复制密文时,这不会起作用。
    IV不应该是秘密的。一种常见的方法是将密码与密文一起传递,然后在解密之前将其切掉。

  • 您没有进行任何完整性检查。最好对您的密文进行身份验证,以便像padding oracle attack这样的攻击是不可能的,您可以检测密文是否被(恶意)篡改或密钥输入错误。这可以使用经过验证的模式(如GCM或EAX)或encrypt-then-MAC方案来完成。

  • Rijndael通常支持128,192和256位的密钥大小。一个字节通常有8位,因此相当于16,24和32字节键。

  • 用户不输入密钥,因为它们通常需要与随机噪声和特定长度无法区分。最好让用户输入密码,并使用高迭代次数/成本因子从PBKDF2,bcrypt,scrypt或Argon2中获取密钥。