2011-11-09 121 views
1

我已被授予加密數據的任務,這些數據將存儲在我們的數據庫中併發送給我們的客戶之一。我認爲最好的方法是使用非對稱加密,這樣一旦我們用客戶的公鑰將其加密後,客戶(私鑰的所有者)就可以將其解密。C# - 使用第三方公鑰加密發送給第三方的數據

我想將我們客戶的公鑰,算法類型(RSA或DSA)和截止日期存儲在我們的數據庫中,而不是管理其證書。問題是我如何存儲和使用他們的公鑰?我創建了以下小程序來測試,並且遇到了問題。

class Program 
{ 

    static void Main(string[] args) 
    { 
     const string publicKeyString = "30 81 89 02 81 81 00 c2 6e 7e e8 78 66 3d 74 fd a7 57 21 24 2d c0 ee 53 59 54 14 db f5 cb 5e 8c 64 c8 73 d5 83 d7 12 57 3f e2 92 54 9a 87 94 18 71 04 c8 b5 92 44 27 78 e9 d3 de cb 5f f6 93 75 c0 46 6b 50 c7 45 a8 38 f9 a1 83 8e 26 51 5a 8c 22 95 8e 2b 4c 10 ea c6 85 ed 02 ed 66 81 ef a3 55 15 ad 64 33 d3 bd ca 75 db 35 44 49 54 ef 6a ca 2a d5 90 a7 9b be 03 40 62 16 fd be 39 fb b6 f0 6b f8 f1 00 c0 c5 02 03 01 00 01"; 
     const string stringToEncrypt = "11111111111111111111"; 

     var encoding = new UTF8Encoding(); 
     var encryptedData = Encrypt(encoding.GetBytes(stringToEncrypt), encoding.GetBytes(publicKeyString)); 

     Console.WriteLine("**** Encrypted String ****"); 
     Console.WriteLine(encoding.GetString(encryptedData)); 

     var decryptedData = Decrypt(encryptedData); 

     Console.WriteLine("**** Decrypted String ****"); 
     Console.WriteLine(encoding.GetString(decryptedData)); 

     Console.ReadKey(); 


    } 

    static byte[] Encrypt(byte[] dataToEncrypt, byte[] publicKey) 
    { 

     var exponent = new byte[] { 1, 0, 1 }; 
     var rsa = new RSACryptoServiceProvider(); 
     rsa.ImportParameters(new RSAParameters() { Modulus = publicKey, Exponent = exponent }); 
     var encryptedData = rsa.Encrypt(dataToEncrypt, false); 
     return encryptedData; 
    } 

    static byte[] Decrypt(byte[] dataToDecrypt) 
    { 
     var cert = new X509Certificate2(@"C:\certs\BP_DEV_CERT_1024.p12", "password"); 
     var rsa = (RSACryptoServiceProvider) cert.PrivateKey; 
     var decryptedData = rsa.Decrypt(dataToDecrypt, false); 
     return decryptedData; 

    } 

} 

當我運行這個程序時,我得到「要解密的數據超過了這個128字節模數的最大值。」這使我相信我準備的方式 使用的公鑰是完全錯誤的。

所以我想我需要知道兩件事情:

  1. 我可以複製從證書的公鑰,但我應該怎樣把它存儲在數據庫中?

  2. 我應該如何正確地將公鑰字符串轉換爲正確的字節數組?

  3. 其他可能有的指針。

+0

我剛剛意識到我需要做的第一件事是將公鑰(它是一個十六進制轉儲)轉換爲字節數組。 – idflyfish

+1

如果這解決了您的問題,您應該將其作爲答案發布。 –

+0

這可能是你必須等待一段時間才能回答自己的問題,但請做! – Marijn

回答

1

RSA和其他非對稱算法不適合批量加密數據。最大消息長度比密鑰模數少了幾個字節。當然,您可以將數據組成塊並反覆應用RSA加密,但這仍然非常緩慢。相反,RSA用於交換對稱密碼的加密密鑰。

我建議您使用S/MIME來加密客戶的數據。這是一個廣泛審查安全性的標準,您可能已經有一個庫來支持該協議。大多數電子郵件客戶端都支持S/MIME,因此您的客戶可能已經擁有了他們需要的軟件。

S/MIME(和PGP)通過生成對稱密碼的密鑰,如AES —「內容加密密鑰」。這用於加密消息。然後該對稱密鑰用每個接收者的「密鑰加密密鑰」—的公共RSA密鑰—加密。加密的內容加密密鑰與密文一起發送給每個收件人。

+0

我想過,但數據只是一個簡短的字符串......不超過20個字節。 – idflyfish

+0

@idflyfish您將遇到的另一個問題是您將密文(在0-255範圍內的隨機字節)轉換爲UTF-8字符串;由於在UTF-8下將會有字節序列不映射到字符,因此密文將被破壞。相反,使用類似Base-64或者十六進制的東西從你的字節數組中產生文本。 – erickson

+0

謝謝。我結束了使用十六進制來表示字符串。很棒。 – idflyfish