web-dev-qa-db-ja.com

IVがすでにランダムに生成され、暗号化されたデータとともに保存されているのに、なぜAES-CBSのソルトが必要なのですか?

私はこのコードを見ていて、ソルトなしでの暗号化は安全ではないというこれらのコメントに出くわしました。各値にすでにランダムIVを使用しているのになぜ安全でないのですか?コメントは間違っているかもしれませんが、人気の逸品なのでわかりませんでした。 keyは本当にpasswordとして扱われていると思います。

https://github.com/attr-encrypted/encryptor/blob/master/lib/encryptor.rb#L57

_  if options[:iv]
    cipher.iv = options[:iv]
    if options[:salt].nil?
      # Use a non-salted cipher.
      # This behaviour is retained for backwards compatibility. This mode
      # is not secure and new deployments should use the :salt options
      # wherever possible.
      cipher.key = options[:key]
    else
      # Use an explicit salt (which can be persisted into a database on a
      # per-column basis, for example). This is the preferred (and more
      # secure) mode of operation.
      cipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(options[:key], options[:salt], 2000, cipher.key_len)
    end
  else
    cipher.pkcs5_keyivgen(options[:key])
  end
_

私は何かをゼロから書くつもりで、ベースライブラリのみを使用します。私のキーはSecureRandom.base64(32)からのもので、コードに格納し、Base64でデコードしてバイナリキーを取得し、それを暗号化/復号化に使用します。また、各データ要素のランダムIVも使用します。塩は必要ないと思います。確認したいです。

9
Chloe

実行するときに、塩とIVの両方が必要です。2つの異なるアクション、1つは塩が必要、もう1つはIVです。それはあなたのケースです。

ソルトは、パスワード秘密鍵。それがあなたのサンプルコードで使用されているものです: PBKDF2パスワードベースの鍵導出関数です。パスワードを使用するものと同じように、PBKDF2には設定可能な低速(「2000」パラメーター)と一意性が必要です。 。これは、パスワードハッシュのサブケースであり、 説明 です。

IVは、実際の暗号化に必要です。 CBCモード は順次アルゴリズムであり、各データブロックは最初に前のブロックの処理の出力とXORされます。どこかで開始する必要があります...したがって、IVは最初のブロックに使用される任意の「前のブロック」です。

一般的に言えば、CBCモードでは一様にランダムなIVが必要であり、暗号化するデータの一部を選択する立場にある攻撃者が予測することはできません(BEAST攻撃SSLではそのようなものです)。ただし、同じキーを2回以上使用した場合にのみ問題が発生します。したがって、次の2つのトリックを適用でき、暗号化されたファイルに沿ってIVを送信する必要がなくなります。

  • PBKDF2は、構成可能な長さの出力を生成するために使用できます。 PBKDF2を使用すると、キーおよびIVに十分なバイトを生成できます。
  • 従来の固定IV(「すべてゼロ」など)が使用されます。

特定の暗号化キーが1回だけ使用されている場合、どちらの方法も有効ですonly。つまり、同じパスワードを使用して2つのファイルを暗号化する場合、各ファイルに対して新しいランダムソルトを生成する必要があります。これはを意味します。パスワードからキーへの変換に計算コストがかかり(そしてそうでなければなりません)、多くのファイルを同じパスワードで暗号化する必要がある場合、総コストは禁止。

If同じソルトが複数のファイルに(同じパスワードで)使用されている場合(*)、その結果、すべてに同じキーが使用されますこれらのファイルは問題ありません...各ファイルが独自のIVも取得する限り。そのため、IVは何らかの方法でファイルヘッダーに格納する必要があります。一方、すべてのファイルが同じソルトを使用している場合は、そのソルトのストレージスペースを相互に関連付けることができますか?

一般的で安全なメソッドは、eachキーの取得方法に関係なく、暗号化が実行されます。これにより、鍵生成プロセスおよびプロトコル全体での発生頻度について暗黙の仮定を行うことが回避されます。また、これにより、「同じパスワード」を使用してバッチプロセスとして多くのファイルを暗号化する場合に、パスワードからキーへの変換を相互化できます。各ファイルが独自のランダムIV、同じキー(派生onceパスワードから、onesalt)を使用して、すべてのユーザーに安全に適用できます。これはどういうわけか [〜#〜] tls [〜#〜] (バージョン1.1以降):所定の接続のすべてのrecordsで発生します同じキーで暗号化されますが、各レコードは独自のIVを取得し、これは安全です(TLS 1.0では、各レコードは前の暗号化レコードの末尾からコピーすることで独自のIVを取得します。これらのIVは、BEASTに対して脆弱です。次に、予測可能を観察して、TLS 1.1+では、各レコードに新しい特定のランダムIVがあります)。

(*)個別のパスワードにソルト値を再利用しないでください。決して。

14
Tom Leek

あなたは正しく理解しています。 見つかったコードには、一般的な命名エラーが含まれています。 私はもともとコードを読み間違えました。トム・リークは正しいです。コードはめちゃくちゃではありませんが、ハッシュ中にソルトを使用してから、暗号化中にIVを使用しています。

多くの人々は、「塩」と「初期化ベクトル」という用語を混同しています。これらは同じ目的を果たしますが、技術的にはさまざまな操作で使用されます。ハッシュにはソルトが、暗号化にはIVが使用されます。どちらの場合も、ランダムな入力を追加することにより、同じ入力が常に同じ出力になることを防ぐことが目的です。

暗号化のコンテキストで「塩」と表示される場合、それはおそらくIVを意味します。ハッシュのコンテキストでIVが見られる場合、それはおそらく塩です。


暗号化するときは、IVを保護する必要があることを指摘することが重要です。保護されていないIVを使用して暗号化されたデータを学習できる種類の攻撃があります。 BEAST(私が覚えていなければ)はそのような攻撃の例でした。この保護は、GCM、XST、またはその他のいくつかの新しい暗号化モードを使用して自動的に取得できます。 CBCのような古い暗号化モードを使用する場合は、署名またはHMACを使用してIVを自分で保護する必要があります。

8
atk