2016-08-27 85 views
1

在YouTube上观看视频后,我使用Rijndael在C#中制作了一个加密程序。它非常简单。如何解密在Rijndael加密中具有超过16个字母的单词

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); 
    } 
} 

和decyption代码的代码是

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); 
    } 
} 

回答

0

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

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


其他注意事项:

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

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

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

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

+0

你能说出我犯过错误的地方吗?这将是一个很大的帮助! –

+0

为什么?你使用'Convert.ToBase64String'和'Convert.FromBase64String'有问题吗?我无法帮助你解决其他问题,因为那样做太多了。你为什么不使用[RNCryptor](https://github.com/RNCryptor/RNCryptor-cs)来解决所有这些问题,并且是安全的? –

+0

我刚才提到我已经从YouTube复制了这个!我真的不知道密码学仍然存在。这就是原因。但我需要这段代码才能正常运行我的项目之一! :) –