コンテンツを暗号化するために、既存の S/MIME (または CMS) 実装と堅牢な暗号化モジュールを使用することをお勧めします。
S/MIME エンベロープ データは、暗号化されたデータを「保管中」に保存するための適切な形式です。エンベロープには、使用されるアルゴリズムとキーに関する情報が記録されるため、承認された受信者が後で必要なときにその情報を利用できるようになります。
また、「最良の」アルゴリズム (ECDH 鍵協定など) をサポートしていなくても、一般的なプログラマーが作成したものよりも、優れたライブラリに脆弱性が存在する可能性ははるかに低くなります。暗号解読よりも実装エラーによってセキュリティが侵害される可能性がはるかに高いため、これらのエラーを最小限に抑えることは理にかなっています。
正当なプロトコルでは、公開鍵は少数の信頼できる発行者の 1 人によって署名され、その公開鍵は何らかの安全な手段によって「帯域外」で配布されます。メッセージ送信者への公開鍵を取得するための安全な手段が既にある場合、わざわざ別の手段を送信する必要はありません。そうしないと、めちゃくちゃになります。
TLS と S/MIME は、すべてのクライアントで既知の CA 証明書のセットを持っていることに依存しています。これらは、サーバーの公開鍵に署名するために使用され、クライアントが鍵の置き換えの試みを検出できるようにします。プロトコル自体はブートストラップできません。「トラストアンカー」をアウトオブバンドで配布する安全な方法が必要です。
また、RSA は対称暗号に比べて非常に遅いことにも注意してください。実際のプロトコルは、AES のような対称アルゴリズムの「コンテンツ暗号化キー」を生成し、RSA 公開キーを「キー暗号化キー」として使用して、メッセージ受信者のコンテンツ暗号化キーを暗号化します。
したがって、主な問題は、公開鍵をクライアントに安全に渡すことです。それができる場合は、オプション #1 または #2 のいずれかが適しています。別の公開鍵を「帯域内」で送信しようとするのではなく、その公開鍵を使用するだけであると仮定します。実際、CMSでは、オプション #1 は「鍵トランスポート」と呼ばれ、オプション #2 は「鍵合意」と呼ばれます。
実際には、「サーバー」は、すでによく知られている CA によって発行された証明書を使用するか、クライアントが証明書のハッシュを電話で伝えたものと比較するか、崖の表面に刻み込むことができます。または何でも。重要なことは、すべてのセキュリティは証明書の完全性に依存するということです。改ざんから保護する必要があります。
Crypto++ は「業界標準」ですが、そのセキュリティは使用方法によって異なります。 Jerry が Kramer に語ったように、「ドアは…閉じている必要があります!」 設計が不十分なプロトコルで Crypto++ の暗号化プリミティブを使用すると、どこにも行き着きません。そのため、優れた暗号化モジュール (暗号化プリミティブ) と共に CMS (上位レベルのプロトコル) を使用することを強調しています。