web-dev-qa-db-ja.com

秘密鍵で暗号化/公開鍵で復号化できますか?

[免責事項:私は知っています。暗号について何か知っているなら、おそらく私が間違っている理由を私に教えようとしています-これは典型的な応答のように思われるのに十分なグーグル検索を行いました。]

次のように仮定します。特定のドメインに対してログインCookieを発行したい中央機関があるとします。このドメインでは、必ずしもすべての人を信頼する必要はありませんが、Cookieを読み取ることができる重要なエンドポイントがいくつかあります。少し言いますが、実際には、この「信頼できる」パートナーの数は多くなる可能性があります。 Cookieには、ユーザー名、タイムスタンプ、有効期限、乱数などの多くの情報は含まれていません。もちろん、(理由の範囲内で)暗号化した後でも、パフォーマンス上の理由から、サイズは小さくしておく必要があります。現在、2つのセキュリティ問題があります。

1)このドメインのすべてのウェブサーバーをユーザーデータで信頼するわけではありません。このため、Cookieを読み取る機能は、これらの信頼できるパートナーに制限する必要があります。 2)ユーザーのデータを保護するためにこれらのパートナーを信頼していますが、権限の中心点を偽造できないようにしたいと思います(ここでも、合理的な範囲内で)。

これで、認証局の秘密RSA鍵を生成して秘密にし、公開鍵を「信頼できるパートナー」にのみ配布すると、秘密鍵で暗号化して、公開鍵を持っている人が誰でも読み取れるようになります。 。私が明確にしていないのは、メッセージに署名する必要があるのでしょうか、それとも復号化する行為は、メッセージが秘密鍵で生成されたことの証拠でしょうか?これは、この方法が、関係するすべての関係者に対称鍵を配布し、それを使用して暗号化し、秘密鍵を単に署名するために使用するよりも良いまたは悪い方法ですか?そしてもちろん、これが愚かな考えであるすべての方法を自由に教えてください。しかし、実用的な議論はおそらくアリスとボブを改造するよりも説得力があることを覚えておいてください。

ああ、そして実装の指針は大歓迎ですが、役に立つであろう「落とし穴」があれば、Googleで基本を見つけることができます!

24
agnoster

シナリオのintegrity問題を解決することを目的とした、何らかのデジタルシグナチャスキームまたはその他のメカニズムを使用する必要があります。

暗号化自体では不十分です。解読されたメッセージがどうあるべきかをどうやって知っていますか?正しいキーで暗号化されたCookieを復号化すると、「有効な」Cookieが確実に提供されますが、間違ったキーで暗号化されたCookieを復号化するとどうなりますか?または単に意味のないデータですか?まあ、あなたはちょうど有効なクッキーを取得するかもしれません! (タイムスタンプは有効と見なす範囲内にあり、ユーザー名は合法であり、乱数は...ええと...数値などです)。

私が知っているほとんどの非対称暗号化アルゴリズムでは、組み込みの検証はありません。つまり、間違ったキーでメッセージを復号化しても「失敗」することはありません。誤った平文しか得られないため、あなたは有効な平文と区別する必要があります。ここで、デジタル署名を使用して、最も一般的に整合性が発揮されます。

ところで、RSAは長い間研究されており、いくつかの「落とし穴」があります。そのため、ゼロから実装する場合は、「比較的壊れやすい」キーの作成を回避する方法を先に読むことをお勧めします。

5
M.A. Hanin

Nate Lawsonが here および here を説明する理由は、公開鍵を密接に保持された秘密の復号化鍵として安全に使用できない理由です(それは微妙な点であり、他の多くの誤りもたくさんあります)あなたの前に作ったので、気分を害しないでください!).

公開鍵を使用して信頼性を確保し、秘密鍵を別の対称鍵として使用するだけです。

私は公開鍵システム、特にRSAに対する興味深い攻撃について十分に読んだので、この結論に完全に同意します。

公開鍵暗号システム、特にRSAは非常に脆弱です。それらが設計された以外の方法で使用しないでください。

(つまり、公開鍵で暗号化し、秘密鍵で署名するなど、他のことはすべて火で遊んでいます。)

補遺:

結果のCookieのサイズを小さくしたい場合は、RSAではなくECDSAを使用して署名を作成することを検討してください。ECDSA署名は、同等のセキュリティ要素のRSA署名よりもかなり小さいです。

19
caf

暗号化では、あなたが知っていることです。あなたのシナリオでは、あなたはあなたのクッキーを発行することができる中央の権限を持っており、他のエンティティが同じことをできるようにしたくありません。したがって、中央当局はいくつかの個人データを「知っている」必要があります。また、「信頼されたWebサーバー」がCookieのコンテンツにアクセスできるようにしたいのであり、誰もがCookieを読み取れないようにする必要があります。したがって、「信頼できるWebサーバー」にも独自のプライベートデータが必要です。

通常の方法は、当局がCookieにデジタル署名を適用し、Cookieが信頼できるWebサーバーに既知の鍵で暗号化されることです。あなたが考えていることは次のようになります:

  • RSA係数nと2つの通常のRSA指数deed = 1 modulop-1andq-1wheren = pq)。中央当局はd、信頼できるWebサーバーを知っています知っているe、係数nはパブリックです。
  • Cookieは、中央当局によって整数cモジュロnにパディングし、計算s = c ^ dmodn
  • 信頼できるWebサーバーは、c = s ^ emodnを計算することでCookieデータにアクセスします。

そのようなスキームはうまくいくかもしれませんが、私はそれに次の問題を見つけます:

  • 基本的なセキュリティのために、eは大きくなければなりません。通常のRSA記述では、eは公開指数であり、(e = 3のように)小さいです。小さな指数は公開されている場合は問題ありませんが、Cookieのコンテンツに第三者がアクセスできないようにするため、eを十分な大きさにして、徹底的な検索に抵抗する必要があります。同時に、信頼できるWebサーバーはpqを知らないで、n。これは、信頼できるWebサーバーが、係数と係数を知らずに、大きな係数と大きな指数で計算する必要があることを意味します。これはマイナーなポイントのようですが、多くのRSA実装ライブラリを失格にします。あなたは大きな整数(そして「サイドチャネルリーク」として知られているすべての実装の問題)で「自分で」いるでしょう。
  • RSA署名の耐性とRSA暗号化の耐性は十分に研究されていますが、一緒に研究されていません。たまたまパディングが不可欠であり、暗号化と署名に同じパディング方式を使用しないでください。ここでは、署名と暗号化の両方に適したパディング方式が必要です。暗号学者は通常、何百人もの訓練を受けた暗号学者が数年間このスキームを検討し、明らかな弱点を発見しなかった(または見つかった弱点を修正した)場合に、優れたセキュリティが達成されると考えています。家庭で調理したスキームは、ほとんどの場合、セキュリティを実現できません。
  • 多くの人が秘密を知っていれば、それはもはや秘密ではありません。ここで、すべてのWebサーバーがeを知っている場合、新しいeを選択して、残りのすべての信頼できるWebサーバーに対する新しい値。共有対称鍵でも問題が発生します。

同じタイプの機密性と検証可能な完全性を保証する問題は現在研究中です。 signcryption を検索できます。確立された基準はまだありません。

基本的には、署名にのみデジタル署名を使用し、機密性部分に(対称または非対称)暗号化を使用する、よりクラシックなデザインの方が便利だと思います。これにより、最小限の自家製コードで既存のライブラリを使用できるようになります。

署名部分については、DSAまたはECDSAを使用することをお勧めします。これにより、はるかに短い署名が生成されます(通常、1024ビットのRSA署名と同等のセキュリティのDSA署名では320ビット)。中央機関の観点から、ECDSAはパフォーマンスも向上します。私のPCでは、シングルコアを使用して、OpenSSLは1秒あたり6500を超えるECDSAシグネチャ(P-192 NISTカーブ)と1145のRSAシグネチャのみをクランチします。秒(1024ビットのキーを使用)。 ECDSA署名は2つの192ビット整数、つまりエンコードする384ビットで構成されていますが、RSA署名は1024ビット長です。 P-192のECDSAは、RSA-1024と少なくとも同じくらい強力であると考えられています。

6
Thomas Pornin

公開鍵は当然のことながら公開です。秘密鍵で暗号化し、公開鍵で復号化している場合、それは覗き見から安全ではありません。 「このデータは秘密鍵Xを保持する人物Xから送信されます」と鍵の残りの半分が公開されているため、誰でもそれを確認できます。

信頼できないサーバーに公開キーXを置くことを信頼できない誰かに止めさせるにはどうすればよいですか?

2つのサーバー間で安全な通信回線が必要な場合は、それらすべての信頼できるサーバーに独自の公開/秘密キーのペアを持たせる必要があります。そのようなサーバーのキーペアYと呼びます。

その後、サーバーXは秘密キーXと公開キーYを使用してメッセージを暗号化できます。これは、「サーバーXは、Yだけが読み取ることができるメッセージを送信し、YはXからのメッセージであることを確認できる」と言います。

(公開鍵暗号は非常に時間がかかるため、そのメッセージには有効期間が短い対称鍵を含める必要があります。)

これはSSLが行うことです。公開鍵暗号を使用してセッション鍵を設定します。

そうは言っても、ライブラリを使用してください。これは簡単に失敗します。

1
Broam

あなたの質問への答え「解読する行為は、それが秘密鍵で生成されたという証拠になります」、受信者がデータの単純な検証を行うことができる場合、答えはイエスです。 「ユーザー名:ジョン、タイムスタンプ:<番号>、有効期限:dd/mm/yyyy」とします。誤った公開鍵を使用して復号化すると、「ユーザー名:<一部の文字>、タイムスタンプ:<数字のみ>、有効期限:??/??/????」が表示される可能性があります。ゼロです。 「ユーザー名:[a-zA-Z] +、タイムスタンプ:[0-9] +、有効期限:....」のような正規表現(regex)を使用して検証すると、検証が失敗します。正規表現は通常「ユーザー名:」で失敗するため、間違った公開鍵が使用された場合、日が1〜31、月が1〜12であるかどうかを確認することもできます。検証が成功した場合でも、タイムスタンプを確認して、リプレイ攻撃がないことを確認する必要があります。

ただし、次の点を考慮してください。

  1. RSA公開鍵暗号は、攻撃者に悪用される可能性があるため、構造化データの一括暗号化用には設計されていません。公開鍵暗号は、通常2つの方法で使用されます。1)対称暗号鍵(定義上、構造はありません)を安全に転送し、一括暗号化で使用します。これは、公開鍵を使用して対称鍵を暗号化し、2)文書ではなく文書のハッシュ(これも構造のないもの)を秘密鍵を使用して暗号化することにより、文書にデジタル署名します。あなたの場合、あなたは明確な構造を持つクッキーを暗号化しています。
  2. あなたは、公開鍵が間違った人やエンティティの手に渡らないことに依存しています。
  3. 公開鍵暗号化は、対称鍵暗号化よりも約1000倍遅くなります。これはあなたの場合の要因ではないかもしれません。

このアプローチを引き続き使用し、公開キーのみを「信頼できるパートナー」に配布できる場合は、ランダムセッションキーを生成する必要があります(つまり、対称鍵)、秘密鍵を使用して暗号化し、公開鍵を持つすべての受信者に送信します。次に、セッションキーを使用してCookieを暗号化します。セッションキーは定期的に変更できます。まれに、公開鍵を変更することもできます。新しい公開鍵と秘密鍵のペアを生成し、セッション鍵で公開鍵を暗号化して、すべての受信者に送信できます。

1
Babu Srinivasan

私はあなたが「信頼できるパートナー」を信頼してクッキーを解読して検証すると思いますが、彼らが彼ら自身のクッキーを生成できるようにしたくないのですか?それが問題でない場合は、はるかに単純なシステムを使用できます。すべての関係者に秘密鍵を配布し、それを使用してCookieを暗号化し、HMACを生成します。公開鍵暗号、複数の鍵は必要ありません。

0
Nick Johnson

アプリケーションに適しているかどうかにかかわらず、キー配布アプローチの代わりとして、対称キー暗号化を使用する Kerberos の使用を検討してください。これは、すべてのキー情報を制御する単一の高度に保護された要塞サーバーです。そして巧妙なプロトコルのセット( Needham-Schroderプロトコル を参照)

0
Chris Owens