web-dev-qa-db-ja.com

暗号化ファイル共有プロトコルの設計

学習プロジェクトとして、ドロップボックスを介して友人とファイルを安全に共有する方法を実装しようとしています。 (私は既存のソフトウェアを探していません。これを正しく行う方法を学ぶためにこれを行っています。)

もちろん、私は自分の暗号化アルゴリズムを発明しようとはしません。

友人に安全に送信したいファイルがあります。
私たち2人は、自分のマシンにプロジェクト予定と共有ドロップボックスフォルダを持っています。 (転送手段は無関係である必要があります)。

私たちはそれぞれRSA鍵ペアを持っています。私たちは安全な方法(USBスティックを介して、またはGPGされた電子メールを介して)を使用して公開鍵を交換しました。

私が使用します

4096ビットのキーサイズのRSACryptoServiceProvider

これらのキー。
(テストアプリケーションでの8〜11秒の大きな一時停止は、RSAキーペアの生成や暗号化ではなく、key2stringまたはkey2base64 操作!)

キーはテキストファイルにローカルに保存されます。秘密鍵は、

CBCモードのAESCryptoServiceProvider、PKCS7パディング、256ビット。

IVは、CSPによって完全にランダムに生成されます。
対称鍵は、以下を使用してパスワードから導出されます

Rfc2898DeriveBytes(== PBKDF2)、1000イテレーション、RNGCryptoServiceProviderからのソルト。

(ソルトの長さ==最終的なキーの長さ)

ファイルは暗号化され、再び使用します

CBCモードのAESCryptoServiceProvider、PKCS7パディング、256ビット。

キーとIVは、CSP自体によって生成されるファイルごとに完全にランダムになります。

IVは暗号化されたファイルデータの前に追加されます。
このパッケージは、

ランダムなキーを持つHMACSHA512。

RNGCSPとHMAC内部randomkeygenのどちらを使用するかわかりません。これまでは、内部メソッドの安全性を見つけることができなかったためです。 (これはNIST承認済みですか?)

HMACはIV:cryptedfileパッケージの前に追加されます。

HMACキーとAESキーは私の友人の公開キーで(個別に)暗号化され、そのような暗号化された形式でパッケージに付加されます。

cryptedAESKey:cryptedHMACKey:HMAC:IV:cryptedfile

このパッケージは、オリジナルと同じ名前と拡張子を使用して、共有DropBoxフォルダーにバイナリとして保存されます。
これは、ファイル名についてはまだ何も解決しておらず、考えもしていないためです。提案は大歓迎です。

もちろん受信側では、プロセスは逆に機能します。

  1. 秘密鍵のロックを解除するにはパスフレーズを入力してください
  2. hMACとAESキーを復号化する
  3. ファイルを認証する
  4. キーとivを使用して復号化する
  5. 元のファイル名で保存

それで、私はそれを正しくしていますか?
言い換えれば、何か問題が見られますか、どっちつかず、立ち入り禁止、私の側の誤解などは何ですか?私のプロジェクトについて、あなたの経験豊富な評決を探しています。さらに、何がより良く、異なって、まったくできないのでしょうか? 学んだ教訓 のすべてのこと、そして私の研究が明らかにしたすべてをカバーしたと思います。

現在、コミュニケーションの存在を隠すことには興味がありません。さらに、私のアプリケーション内のキーハンドリングも今は対象外です。暗号化の部分が正しくなった後、次のステップ(ダンプなどからメモリを保護する)としてそれを取り上げます。

5
ro_m

learningではなく、usingではなく、独自の暗号を作成することは問題ありません。

暗号化にはいくつかの「層」があります。 RSA、AES、SHA-256などのアルゴリズムがあります。次に、アルゴリズムをまとめるプロトコルがあります。そして、プロトコルを実行可能なコードに変換するimplementationsがあります。暗号化を最初に理解するために、私は通常、最初に実装に進むことをお勧めします。既存のプロトコルを取得して実装することです。これには、他の人に対して実装をテストする可能性など、いくつかの素晴らしい利点があります。これは、バグの追跡に優れています。これにより、プロトコルの構造に関する洞察も得られます。ストリーム操作をサポートします。

ファイルを単一のメッセージとして送信することに集中しているため、モデルは OpenPGP が解決しようとしているものに近いように見えます。したがって、C#でOpenPGPの実装を機能させることをお勧めします。

独自のプロトコルを今すぐ作成することを選択した場合、選択について次のことが言えます。

  • キーサイズが多すぎます。 256ビットのAESキーは、実際にはまったく役に立たないものです。128ビットのキーは、既存の技術では破壊可能なものをすでにはるかに超えているためです(例 この答え を参照)。同様に、4096ビットのRSA鍵は特大です。 2048ビットはすでにセキュリティを確保するのに十分以上です。大きなキーはパフォーマンスの低下を意味するため、特大のキーは達成できることを表さない非現実的な速度低下を意味し、その結果、全体の教育的価値が低下します。

  • 逆に、1000ラウンドのPBKDF2は小さすぎると見なすことができます。パスワードからキーへの変換では、「マッスルショー」のための反復があり、パスワードの固有の弱点(つまり、それを覚えておかなければならないミートバッグの固有の弱点)に対処します。その反復回数が許容できる限り高くなるようにしたいので、コンピューターの能力と忍耐力に関連しています。今日のコンピューターでの一般的なカウント値は、約10万、場合によっては数百万です。

  • ファイルの暗号化には [〜#〜] mac [〜#〜] を使用しますが、秘密鍵の暗号化には使用しません。これは奇妙に見えます。 MACが不要な状況がありますが、暗号化が保証されているほとんどのコンテキストでもMACが必要です。両方の暗号化で同じ形式を使用する方が簡単です。

  • あなたは暗号化されたファイルにMACを適用します:それは encrypt-then-MAC であり、それは良いことです-そしてあなたdidは暗号化IVの部分を作ることを考えますMAC入力のより良いです(それはあなたがきちんと避けた古典的な間違いです)。ただし、将来のアルゴリズムの俊敏性にある程度の余裕を持たせることをお勧めします。ある時点で、別の対称暗号化アルゴリズムを使用することもできます。その場合、暗号化アルゴリズムのいくつかのシンボリック識別子もMAC入力の一部である必要があります。これは、値0x00の最初のバイトと同じくらい単純で、255の他の将来のアルゴリズムの根拠を残します。

  • SHA-512でHMACを使用するのは悪くありませんが、SHA-256も悪くないため、32ビットシステムでパフォーマンスが大幅に向上します。ここでも、最大の出力とキーサイズへの競争は人工的で無菌です。 SHA-256は「十分な安全性」以上のものです。

  • CBCモードと個別のMACは「古いスタイル」です。暗号化とMACを単一のプリミティブ内で組み合わせ、実装エラーの可能性のある範囲を削減する最新の暗号化モードがあります。特に、 [〜#〜] eax [〜#〜] および [〜#〜] gcm [〜#〜] です。 .NETがそれらを(まだ)提供していないことを理解しています。 CipherMode は、CBC、CFB、CTS、ECBおよびOFBに限定されます。その場合、CBCは最悪の選択ではなく、追加のMAC(つまり、HMACなど)があります。 CBCを適切に使用するには、予測不可能なランダムIVが必要であり、それがあなたの提案です(良い)。

  • 復号化を実装するときは特に注意してください。最初にMACを検証し、次にMAC検証が成功した場合のみ、復号化を続行できます。トリッキーなポイントはパディング処理にあります。攻撃者は変更されたファイルを送信して受信者から秘密を抽出し、受信者の反応を確認する可能性があります。受信者が構文的に有効なパディングを見つけたかどうか。これが Oracle攻撃のパディング の基礎です。着信データをブロックで処理し、MACと推定復号化の両方を並行して計算できますが、最後のブロックについては、最初にMACを計算してチェックするように注意してください(これは、GCMまたはEAXで回避されるハードルの一種です) )。

  • AESの鍵とHMACの鍵の暗号化は奇妙です。創造的な攻撃者がそれらを入れ替えて、受信者にHMACキーを復号化に使用させたり、その逆を可能にする可能性があります。メリットは明らかではありませんが、脆弱性がそのように存在するかどうかを判断するのは非常に困難です。これは、明確に定義されておらず、いずれにしても徹底的に調査されていない特性である、HMACからのAESの「相違」に依存しています。

    単一の「マスターキー」[〜#〜] k [〜#〜]を使用し、受信者の公開キーで暗号化して、いくつかの Key Derivation Function を使用して、AESキーとHMACキーを導出します。 [〜#〜] k [〜#〜]を256ビットの鍵(ランダムに生成)にして、AESともう1つはHMAC用です。または、[〜#〜] k [〜#〜]を長く(またはさらに短く)し、SHA-256でハッシュし、SHA-256出力を2つに分割することもできます半分。ポイントは、2つではなく1つのRSA暗号化が必要なことです。また、単一のソースから暗号化キーとMACキーを取得すると、GCMまたはEAXの将来の使用に、より適切にマッピングされます。

  • お使いのファイル形式は、ストリーム処理を許可していません。あなたのフォーマットでは、MACは完全な暗号化ファイルに対して計算されますが、その値が最初に、暗号化結果の前にに来ます。つまり、送信者は送信を開始する前にファイル全体を処理する必要があります。したがって、1 GBのファイルの場合、1 GBの一時ディスク領域(またはRAM)が必要になります。これは、MAC値が接頭辞に格納されるのではなく、末尾に追加される場合は回避できます。

    このバッファリングの問題は、受信者に必ず存在することに注意してください。受信者は、何らかの方法で復号化されたデータを使用する前にMACを検証する必要があります。これに完全に対処するには、それぞれ独自の暗号化とMACを備えた中程度のサイズのチャンクと、安全なアセンブリ用の接着剤を使用して、より複雑な形式を作成する必要があります。モデルは SSL/TLS になります。

  • 認証はありません!受信者は、自分が実際に受け取ったファイルが疑わしい送信者から来たものかどうかを知る方法がありません。認証を追加するには、セットアップで デジタル署名 が必要です。適切に適用された場合、デジタル署名がMACを置き換える可能性があることに注意してください。これは簡単に保証されるプロパティではありません。完全な構造に対して(送信者の秘密鍵を使用して)署名を単純に計算する方が安全です。

  • リプレイ攻撃 に対する保護はありません。攻撃者は、転送中のファイルを観察して、同じファイルを後日再度送信する可能性があります。そのような重複を検出するための対策を講じるのは受信者次第です。これは、データファイル内のどこかの日付のように、MAC(およびおそらく暗号化である必要はありませんが)の保護の下で単純なものにすることができますが、多少の考慮が必要です。

  • 秘密鍵を自分で暗号化することで、オペレーティングシステムに処理を任せないことを理解しています。これには制限がある場合があります。実際、 RSACryptoServiceProvider インスタンスは、物理的に スマートカード にあるキーを使用する可能性があります。さらに、ソフトウェアキーの場合でも、OSにストレージを処理させることで、セキュリティ上の利点が得られます(OSにはハードウェアへの特権アクセスがあり、たとえば、秘密キーのディスクへのリークを回避できます virtualメモリ )。明示的なキーfileを使用することにより、システムがそのような潜在能力と互換性がなくなります。これは残念です。

  • メタデータ、特にコンテンツタイプの余地はありません。同じバイトシーケンスはいくつかの解釈を持つ可能性があり、受信者がPDFまたはその逆としてHTMLファイルを開くように誘導できる場合、面白い結果が生じる可能性があります。理想的には、実際に暗号化する必要がありますデータのタイプの指定を含むヘッダー(例: media type )の後にデータ自体が続く構造体です。

これらはすべて、特定の順序ではなく、網羅性を主張することなく述べられています。総合的な結論は、プロトコルの設計は単純ではないということです。これは、設計の基礎となる、確かな実装経験があると役立ちます。

25
Thomas Pornin

たとえば、1024ビットのThreefishな​​ど、いくつかの新しいブロック暗号を使用して実装してみてください。また、3つ以上のブロック暗号の組み合わせを使用してみてください。これらの暗号の1つでアルゴリズムが破られるのを防ぎます。 TruecryptがAES、Twofish、Serpentの組み合わせをどのように使用しているかを調べてください。おそらく、3つの主要な超大国のそれぞれからアルゴリズムを使用します。 1つはロシアから、もう1つは中国から、もう1つは米国からです。

MACの暗号化についても考えられます。UMAC仕様を参照してください。 NISTハッシュ関数コンテストのファイナリストの1人を使用することを検討してください。 Skeinを使用すると、1024ビットHMACを使用できます。

現在または近い将来に潜在的な敵が量子コンピューターを持っていると仮定すると、128ビットの暗号化はGroverのアルゴリズムを使用して64ビットに削減されます。ブルートフォース検索では、256ビットハッシュは128ビットに削減されます。

この投稿は、モデレーターにより間もなく投票/削除/検閲されます。

0
nolies