2012-03-11 33 views
7

首先,我僅爲學術目的編寫了以下代碼。我之所以這麼說是因爲我沒有把它放在生產環境中,爲此我「繞過」了一些我需要做的事情,我只需要能夠使用加密/解密字符串下面的代碼。我可以做幾次,但由於某種原因,我開始收到「CryptographicException Bad Data」,我不確定是什麼原因導致了這個問題。「Bad Data」CryptographicException

private string RSAEncrypt(string value) 
    { 
     byte[] encryptedData = Encoding.Unicode.GetBytes(value); 

     CspParameters cspParams = new CspParameters(); 
     cspParams.KeyContainerName = _rsaContainerName; 
     using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
     { 
      encryptedData = RSA.Encrypt(encryptedData, false); 
      return Convert.ToBase64String(encryptedData); 

     } 

    } 



    private string RSADecrypt(string value) 
    { 

     byte[] encryptedData = Encoding.Unicode.GetBytes(value); 

     CspParameters cspParams = new CspParameters(); 
     cspParams.KeyContainerName = _rsaContainerName; 
     using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
     { 
      encryptedData = RSA.Decrypt(encryptedData,false); 
      return Convert.ToBase64String(encryptedData); 

     } 
    } 

它只在RSADecrypt調用中引發此異常。

任何想法?我在某處讀取它可能與傳遞到RSA.Decrypt中的encryptedData的預期大小有關的地方。

感謝 }

+0

呃,你是如何通過方法之間的密鑰? – 2012-03-12 19:50:12

回答

13
  • 轉換明文來回使用串編碼一個(即Encoding.Unicode)。

  • 使用Base-64(即Convert.[To/From]Base64String)來回轉換加密的數據;

像這樣:

private string RSAEncrypt(string value) 
{ 
    byte[] plaintext = Encoding.Unicode.GetBytes(value); 

    CspParameters cspParams = new CspParameters(); 
    cspParams.KeyContainerName = _rsaContainerName; 
    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
    { 
     byte[] encryptedData = RSA.Encrypt(plaintext, false); 
     return Convert.ToBase64String(encryptedData); 
    } 
} 

private string RSADecrypt(string value) 
{ 
    byte[] encryptedData = Convert.FromBase64String(value); 

    CspParameters cspParams = new CspParameters(); 
    cspParams.KeyContainerName = _rsaContainerName; 
    using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048,cspParams)) 
    { 
     byte[] decryptedData = RSA.Decrypt(encryptedData,false); 
     return Encoding.Unicode.GetString(decryptedData); 
    } 
} 
6

http://blogs.msdn.com/b/shawnfa/archive/2005/11/10/491431.aspx

不要往返密文通過一個字符串編碼

一個常見的錯誤,人們使用託管加密 類時提出的是,他們試圖存儲通過使用其中一個Encoding類在字符串中加密 操作的結果。那 似乎有道理嗎?畢竟,Encoding.ToString()需要一個 字節[]並將其轉換爲一個字符串,這正是他們尋找的 。

...

相反,如果你想將密文轉換爲字符串,使用 Base64編碼。

...在代碼

結果,每一次工作中,由於基部64的編碼是 保證能夠精確地表示任何輸入字節序列。

有一個很好的,正確這裏例如: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael.aspx

+0

我已經看過那篇文章,但是我沒有完全得到修正或者我需要改變的代碼中的內容......你能幫忙指出一下嗎? – TheJediCowboy 2012-03-11 23:32:07

+0

但是OP使用'ByteConverter.GetString'而不是'Encoding.ToString' – 2012-03-11 23:33:50

+0

@ L.B他的「ByteConverter」是一個UnicodeEncoding! – matthewk 2012-03-11 23:35:19

1

RSA並不意味着加密大對象。你會得到例外是你超過填充限制。實際的限制是基於填充本身(使用false表示您使用的是舊的 PKCS#1 v1.5填充)和公鑰的長度(2048位)。

大對象使用RSA的正確方法是使用對稱密鑰(例如,對稱密鑰)加密大對象。一個256位的AES密鑰)和加密這個密鑰與您的RSA公鑰。

您可以在我的blog上找到執行此類操作的代碼。