1

公開/秘密キー暗号化を使用して、2 つのエンドポイントが相互に安全に通信できるシナリオを実装したいと考えています。シナリオは次のとおりです。

A が B にメッセージを送信するには:

A は、A の秘密鍵を使用してメッセージを暗号化します。

A は、B の公開鍵を使用してメッセージを暗号化します。

A がメッセージを送信します。

Bはメッセージを受け取ります。

B は、A の公開鍵を使用してメッセージを復号化します。

B は、B の秘密鍵を使用してメッセージを復号化します。

B はメッセージを読み上げます。

RSA暗号化を使用してC#にあるものは次のとおりです。

// Alice wants to send a message to Bob:

String plainText = "Hello, World!";
Byte[] plainData = Encoding.Default.GetBytes(plainText);
Byte[] cipherData = null;

RSACryptoServiceProvider alice = new RSACryptoServiceProvider();
RSACryptoServiceProvider bob = new RSACryptoServiceProvider();

var alicePrivateKey = alice.ExportParameters(true);
var alicePublicKey = alice.ExportParameters(false);

var bobPrivateKey = bob.ExportParameters(true);
var bobPublicKey = bob.ExportParameters(false);

RSACryptoServiceProvider messenger = new RSACryptoServiceProvider();
        
messenger.ImportParameters(alicePrivateKey);
cipherData = messenger.Encrypt(plainData, true);

messenger.ImportParameters(bobPublicKey);
cipherData = messenger.Encrypt(cipherData, true);

messenger.ImportParameters(alicePublicKey);
cipherData = messenger.Decrypt(cipherData, true);

messenger.ImportParameters(bobPrivateKey);
cipherData = messenger.Decrypt(cipherData, true);            

String result = Encoding.Default.GetString(alice.Decrypt(cipherData, true));

明らかに、次の行に何か問題があります。

messenger.ImportParameters(bobPublicKey);
cipherData = messenger.Encrypt(cipherData, true);

メッセージ{ "Bad Length" }でSystem.Security.Cryptography.CryptographyExceptionをスローします。

ご覧のとおり、ボブのキーの公開部分だけを使用してデータを暗号化することはできません。

C#でやりたいことを適切に達成する方法について、誰かが光を当てることができますか?

4

2 に答える 2

4

ここで 2 つの問題:

A) プロトコルの設計が間違っています。RSA を使用してメッセージを交換する場合、アルゴリズムは次のようになります。

A は B の公開鍵を使用してメッセージを暗号化します

Aさんがメッセージを送る

B は、B の秘密鍵を使用してメッセージを復号化します

(Bは処理を行います)

B は A の公開鍵を使用してメッセージを暗号化します

Bさんがメッセージを送る

A は、A の秘密鍵を使用してメッセージを復号化します

等々。A が B の秘密鍵を知らないことに注意してください。また、その逆も同様です。公開鍵と秘密鍵は、公開鍵 (全員が知っている) で暗号化されたメッセージを、対応する秘密鍵 (暗号化されたメッセージの意図した受信者だけが知っている) でのみ復号化できるように関連付けられています。実際、これがRSAの要点です。

C# での実装に関しては、根底にある概念を本当に理解すれば、Crypto クラスを扱うのは非常に簡単です。たとえば、ここここを参照してください。

B) RSA は、少量のデータの交換に適しています。これは、共有シークレットを必要としない、安全でないチャネルを介したキー交換を目的としています。「通常の」データの交換には、AES などの対称アルゴリズムが使用されます。したがって、アイデアは、A からランダムなパスフレーズと IV を生成し、A で説明したように RSA 経由で B に送信することです。両当事者がパスフレーズと IV を知った後、共有鍵で AES を使用してデータを暗号化できます。

これが SSL の機能であり、標準の SSL ストリームを使用する代わりに、独自のストリームを展開する十分な理由があるはずです。

于 2012-03-23T08:18:23.483 に答える
1

RSA は、キーより小さいデータの暗号化に使用されます。対称キーを使用して大量のデータを暗号化し、RSA を使用して対称キーを共有します。

詳細については、この質問を参照してください: C# で RSA を使用してファイル (巨大なデータ) を暗号化する方法

于 2012-03-23T06:48:06.550 に答える