2016-03-15 46 views
-1

我已經使用Rijndael算法進行加密和解密。Rijndael解密返回奇怪的輸出

解密工作正常,當我用加密做。

但是,當我嘗試做解密獨自返回這樣的事情

JM「ec4ħdB̵Dq沃頓。

而且我已經使用了兩個按鈕,一個用於加密,另一個用於解密,並在點擊按鈕時調用方法。

我無法理解爲什麼輸出如此返回。即使我使用了相同的轉換(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); 
    } 
} 
+0

你可以檢查從佈雷特張貼在這裏的代碼,它適用於我:http://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string –

回答

0

cs.FlushFinalBlock();遺忘在Decrypt()?我只是往返式操作測試字符串與您的代碼,一旦我固定的

+0

謝謝你的reply.when我嘗試添加cs.FlushFinalBlock();在解密時,它會顯示錯誤消息,如「填充無效且無法刪除」。 – preethi

+0

我有一個頓悟。當你說「單獨解密」時,你的意思是你試圖解密由別人加密的字符串。別人..有不同的設置。只是谷歌該錯誤消息:http://stackoverflow.com/questions/8583112/padding-is-invalid-and-cannot-be-removed;使用與其他人相同的設置。 – zeromus

+0

我已經使用相同的應用程序加密了代碼,關閉並重新啓動它,並在解密輸入框中粘貼相同的加密代碼,當我嘗試單擊解密按鈕時,它會顯示錯誤消息。 – preethi

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作爲參數,其中包含加密的數據,並且更容易將其輸出(其中您不知道確切的長度,由於填充)寫入另一個流。

+0

感謝您的回覆。我已經嘗試執行上面的代碼,並顯示錯誤在行cs.CopyTo(輸出); 「填充無效且無法刪除」。請幫助我 – preethi

+0

@preethi您是使用該功能進行加密和解密嗎?因爲加密和解密的填充必須相同。 – xanatos

+0

該代碼適用於我,我的固定代碼適用於我。他們都給你同樣的錯誤。所以你必須從你粘貼的地方本地修改你的代碼。 – zeromus