2016-08-27 97 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複製了這個!我真的不知道密碼學仍然存在。這就是原因。但我需要這段代碼才能正常運行我的項目之一! :) –