2011-11-09 6 views
1

データベースに保存され、お客様の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

私が最初に行う必要があるのは、公開鍵(16進ダンプ)をバイト配列に変換することだけです。 – idflyfish

+1

問題が修正された場合は、回答として投稿する必要があります。 –

+0

あなた自身の質問に答える前にしばらく待たなければならないかもしれませんが、してください! – Marijn

答えて

1

RSAと他の非対称アルゴリズムは、データを一括して暗号化するのには適していません。最大メッセージ長は、キーモジュラスよりも数バイト少ない。もちろん、データをブロックにしてRSA暗号化を繰り返し適用することもできますが、これはまだひどく遅いです。代わりに、RSAを使用して対称暗号の暗号化キーを交換します。

お客様のデータを暗号化するためにS/MIMEを使用することをお勧めします。これはセキュリティのために広く見直された標準であり、おそらく既にプロトコルをサポートするライブラリを持っています。ほとんどの電子メールクライアントはS/MIMEをサポートしているため、顧客はすでに必要なソフトウェアを既に所有している可能性があります。

S/MIME(およびPGP)は、AES —「コンテンツ暗号化キー」のような対称暗号の鍵を生成することで動作します。これは、メッセージを暗号化するために使用されます。その後、その共通鍵は、公開鍵RSA鍵—、各受信者の「鍵暗号鍵」—で暗号化されます。暗号化されたコンテンツ暗号化キーは、各受信者に暗号テキストと共に送信される。

+0

しかし私はデータが短い文字列であることを考えました... 20バイトを超えてはいけません。 – idflyfish

+0

@idflyfishもう1つの問題は、暗号文(0-255の範囲のランダムなバイト)をUTF-8の文字列に変換していることです。 UTF-8で文字にマップされないバイトシーケンスが存在するため、暗号テキストが破損します。代わりに、バイト配列からテキストを生成するために、Base-64またはhexのようなものを使用してください。 – erickson

+0

ありがとうございます。私は文字列を表すために16進数を使用して終了しました。よく働く。 – idflyfish

関連する問題