web-dev-qa-db-ja.com

「文字列」パスワードをAESで使用されるキーに安全に変換するにはどうすればよいですか?

AESを使用して特定のフォルダーに書き込まれるすべてのファイルを暗号化する必要があるソフトウェアを書いています。どこかに設定されているパスワード/キーが1つあり、それが常に使用されます。

Base64文字列を保存したくないのは、構成を変更しなければならない可能性がある人にとっては複雑すぎるためです。任意の文字を含む文字列を保存したい。このパスワードをAESで使用するキーに変換する最良の方法は何ですか?

  • キーからバイトを取得できますか?
  • LSPBKDF2を使用してキーを生成する必要がありますか?

私が理解しているように、私はまた塩を提供する必要があります。ただし、私の状況では、キーが1つしかないため、ソルトは不要のようです。

  • 空の塩を提供するだけですか、それともどういうわけか安全ではありませんか?
  • それとも完全に異なる(うまくいけばもっと簡単な)方法はありますか?
23

あなたがすることは次のとおりです:

  • 長いキーを生成します(これは安全にランダムに生成された量のデータであり、128ビットを使用できます)
  • このキーを使用して、ファイルをAESで暗号化します(つまり、パスワードとして使用します)
  • パスワードを使用してキー自体をAESで暗号化します(これは少し短いですが覚えやすいです。これで、AESは128、192、または256ビットの長さである必要があるため、パスワードをその長さにする必要があります。そのため、 PBKDF2(またはscryptまたはbcrypt)を使用して、パスワードから固定キー長を作成できますこれを保存しないでください
  • PBKDF2(またはbcryptまたはscrypt)を使用して、ハッシュされたパスワードのハッシュを保持します。これにより、暗号化されたキーを復号化する前に、パスワードが正しいかどうかを確認できます。

そう:

hash(hash(password)) --> can be stored
hash(password) --> cannot be stored

キーが1つしかない場合でも、常にソルトを提供する必要があります(これにより、Rainbowテーブルの検索が大幅に妨げられます)。幸いにも、ソルトの生成はPBKDF2によって自動的に行われます。

つまり、最終的には次の3つになります。

  • 暗号化されたファイル
  • 暗号化されたキー
  • 確認のためのパスワードのハッシュ

キーが必要な理由を尋ねるかもしれません。パスワードを変更する場合(およびすべてのファイルをパスワードで暗号化した場合)、最初にすべてのファイルを元のパスワードで復号化し、次に新しいパスワードで再度暗号化する必要があります。パスワード。この実装では、キーを復号化および再暗号化するだけで済みます(このキーがパスワードとして機能するため)。

[〜#〜]編集[〜#〜]

私はあなたの質問を誤解しました、私は鍵導出関数を追加しました。

また 良い読み (IBM提供)

36
Lucas Kauffman

パスワードをAESキーに変換するには、 PBKDF2 が最も簡単な方法です。パスワードに十分な エントロピー があることを確認してください。

あなたはdoレインボーテーブルの攻撃から保護するためにソルトを使用する必要があるため、ソルトを使用する必要があります。

プラットフォームによっては、これを支援するために利用可能なライブラリがすでにある場合があります。そうでない場合は、Lucus Kaufmanのソリューションに近いものをお勧めします。

セットアップ:

  1. ランダム128ビットキー(k1)、ランダム128ビット [〜#〜] iv [〜#〜] 、およびランダム salt (64ビットはおそらく十分です)。
  2. PBKDF2 を使用して、パスワードとソルトから256ビットのキーを生成し、それを2つの128ビットのキー(k2、k3)に分割します。
    • アルゴリズムのネイティブ出力が256ビット以上であることを確認してください。そうしないと、処理が遅くなります。 PBKDF2 - SHA256 をお勧めします。このために2つの別々のアルゴリズムを使用しないでください。これにより、速度が遅くなり、複雑になりますが、攻撃者の速度が遅くなることはありません。
    • パスワードに十分に高いエントロピーがある場合、かなり少ない反復回数を使用する余裕があります。 1000回の反復は非常に高速であるため、それに気付くことすらありません(特に、プログラムの起動時にキーを復号化するだけでよいため)ので、それを下回る理由はあまりありません。パスワードが弱い場合は、反復回数を増やして補正できます。
    • これには bcrypt を使用することはお勧めしません。出力が間違ったサイズであり、再度ハッシュする必要があるため、不要な複雑さが加わるからです。
    • scrypt は任意のサイズの出力を生成できると思うので、可能であればそれを選択するのが良いでしょう(もし望むなら許可されないかもしれません [〜#〜] fips [〜#〜 ] コンプライアンス)。
  3. K2を使用して [〜#〜] aes [〜#〜] ランダムIVを使用してk1を暗号化します。
  4. 暗号化されたキー、k3、salt、IVをどこかにファイルに保存します。

暗号化/復号化:

  1. PBKDF2 +パスワードとファイルのソルトを使用して、k2とk3を再生成します。
  2. K3を確認します。一致しない場合は、パスワードが間違っているか、誰かがファイルを改ざんしています。ここで止まって。
  3. ファイルのk2とIVを使用して、k1を復号化します。
  4. K1を使用してファイルを暗号化または復号化します。

パスワードの変更

  1. Encryption/Decryptionセクションのようにk1を復号化します。
  2. 同じk1を使用して、Setupの手順に従いますが、他のすべてを再生成します(新しいランダムソルトとIV、新しいパスワードからk2とk3を生成します)。

k2をどこにも保存しないでください。 k1を暗号化せずに保存しないでください。これらのいずれかを行うと、システムのセキュリティが損なわれます。

パスワードを変更できることを気にしない場合(これは非常に重要な機能だと思いますが、そうでない場合もあります)、k1に関する手順をスキップし、k2をAESキーとして使用し、k3を使用して確認してください。

[〜#〜] hmac [〜#〜] の別のキーを生成すると便利です。暗号化されたファイルが改ざんされていないことを確認できます。それを行う場合は、128ビットのHMACキーを生成し、それをメインのAESキーで暗号化して保存できます。

10
Brendan Long

キーを生成する場合は、ハッシュ関数が疑似rngのような「ソート」であることを考慮して、何らかの方法でハッシュする必要があります。したがって、PBKDF2は重要な導出方法であり、この目的のために特別に使用されるため、PBKDF2の使用は常に適切です。パスワードを渡すと、パスワードとソルトに基づいて使用できるキーが生成されます。 Saltに関する限り、それはPBKDF2の一部として自動的に使用されるため、心配する必要はありません。

.NETのようなものを使用し、web.configファイルにキーを保存する場合は、web.configの一部をマシンキーまたはRSAキーのいずれかで暗号化できます http://msdn.Microsoft.com/en -us/library/dtkwfdky%28v = vs.100%29.aspx 、これは、RSAキーやマシンキーの保存をWindowsが処理するという点で優れています。ビルドサーバーを使用して、このプロセスを自動化することもできます。

6
nerdybeardo