1.1. パスワード保存

TODO: encrypted とかの表記をかえたほうがよさげ

TODO: ネタはだいたい書いたので, 発表用資料に変換する

1.1.1. パスワード保存の常識(?)

  • パスワードの保存: saltを付けてハッシュ化

    • ハッシュ化するので元のパスワードに復元することは困難
    • saltがあるので違う人が同じパスワードを付けても別のハッシュ値が得られる
  • パスワードの照合: 入力パスワードとsaltをハッシュ化したものと保存したものを比較

1.1.2. GNU/Linuxでのパスワードの保存法

$id$salt$encrypted という形式でパスワードを「ハッシュ」化.

例:

$6$3d1ahuOb$KiH....(略)

以下 [crypt] より(一部変更)

  • 最初の「$」: DESを利用していないことを示す
  • id: ハッシュの識別子
1 | MD5
5 | SHA-256 (glibc 2.7 以降)
6 | SHA-512 (glibc 2.7 以降)
  • salt: お塩(後述)
  • encrypted: パスワード文字列のハッシュ化部分

パスワードを照合する際は, encryptedからパスワードを復元するのではなく, 入力されたパスワードとsaltから計算したものを encrypted と比較する

1.1.3. ハッシュとは

暗号学的ハッシュ関数 - Wikipedia

理想的な暗号学的ハッシュ関数は次の4つの特性を有する。

  • 与えられたメッセージに対してハッシュ値を容易に計算できる。
  • ハッシュ値から元のメッセージを得ることが事実上不可能であること。
  • ハッシュ値を変えずにメッセージを改竄することが事実上不可能であること。
  • 同じハッシュ値を持つ2つのメッセージを求めることが事実上不可能であること。

1.1.3.1. ハッシュの代表例

  • MD5
  • SHA-1
  • SHA-256,512

1.1.4. saltとは

ハッシュの値をかきまぜる「お塩」.

  • 単にハッシュ化するだけでは, 同じパスワードを利用する人が複数いると同じ encrypted が生成される
    • ユーザごとに異なる必要がある
      • ランダムである必要はない
  • サイズ
    • 伝統的なunix: 12bit
    • 現在のGNU/Linux: 96bit
    • [CRYPTOGRAPHY_ENGINEERING] での推奨: ハッシュの出力サイズと同じ

1.1.5. 実際の処理

[CRYPTOGRAPHY_ENGINEERING] p304 の方式 ( || は文字列連結)

x_0 = 0
x_i = h(x_(i-1) || password || salt) for i = 1,....r
K = x_r

[ crypt() アルゴリズム解析 (MD5バージョン) ]

どちらも ハッシュを何度も利用する (stretch)

1.1.6. stretchとは

  • ハッシュを何度も利用することで, ハッシュ値を求めるのに必要な時間を増大させる
    • 攻撃に時間がかかるようになる
      • = パスワードの文字数を伸ばす(stretch)のと同じ効果
  • どれくらいやるのか
    • cryptのMD5の場合: 1000回
    • [CRYPTOGRAPHY_ENGINEERING] での例: 2^20

1.1.7. 実際の処理速度

PHPからsha256を繰り返す呼ぶコードで計測

  • 方式は [CRYPTOGRAPHY_ENGINEERING] のもの
  • パスワード 10byte
  • salt 32byte
  • CPU 1コアのみ利用

50万回の繰り返しが終わるのに 1〜2秒

1.1.8. ハッシュ方式のリスク/stretchの効果

  • 記録された情報のみでパスワードが「保存」されている
    • 弱いパスワードは短時間で破られる
  • 1CPU(4コア)でブルートフォースアタック
    • 前ページの条件(1000回sha256)でパスワード情報が保存されているとする
      • 4コアで1日 172800000 個のパスワードが試せる
      • パスワードの文字種が64bitとすると 4文字(64^4=16777216)は余裕. 5文字(1073741824)は1週間弱, 6文字は1年ちょい.
    • 1000回のstretchがなかったら...
      • 1日 172800000000 個
      • 6文字(68719476736)も半日足らず. 7文字は1月弱
    • 注意点
      • パスワード解析は並列に実行可能
      • プログラムはもっと早くできる
      • 手元ではmd5はsha256の倍以上早かった

1.1.9. なぜUnixではこうなったのか

[認証技術] p8〜より.

  • なぜ可逆な暗号化などではないのか?

    • 秘密の情報を管理するのが難しい. 以下から暗号化の鍵が漏れる可能性がある

      • バックアップファイル
      • システムのバグ
      • 特権ユーザによるアクセス
  • メリット

    • 鍵の管理のコストが不要
    • 生パスワードを復元できない
  • デメリット

    • 弱いパスワードが記録された情報だけで破れる

1.1.10. Webシステムではどうなのか

通常WebサーバとDBサーバは物理的に分離されている(されていない場合もあるが).

Unixよりも秘密の情報とパスワード情報が共に漏洩するコストは低いだろう.

  • 秘密の情報管理のコストはもちろんある
    • 漏洩のコスト
    • 紛失のコスト

1.1.11. 秘密の情報を用いる場合の手法

  • (共通鍵)暗号
  • ハッシュ+暗号
  • 鍵付きハッシュ

1.1.12. (共通鍵)暗号

  • メリット
    • ちゃんと暗号化し鍵が安全ならば, 弱いパスワードも記録された情報だけでは破れない
  • デメリット
    • 鍵を保持するものがパスワードを復元できる
    • 鍵の管理のコストがかかる

1.1.13. ハッシュ+暗号

常識(?)通りにハッシュ化したあとで暗号化

  • メリット
    • ちゃんと暗号化し鍵が安全ならば, 弱いパスワードも記録された情報だけでは破れない
    • 鍵を保持するものでも生パスワードを復元できない
  • デメリット
    • 鍵の管理のコストがかかる

1.1.14. 鍵付きハッシュ

  • saltに秘密の情報を入れてハッシュ?
    • 単純に鍵と平文を文字列連結をしたものをハッシュするMACは期待通りの強度がないという論文

On the Security of Two MAC Algorithms

  • hash(key || salt || password) 的なものはやめたほうがよさそう
  • 鍵付きハッシュを用いるならHMACを応用したほうがよいだろう
  • メリット
    • ちゃんとしたアルゴリズムを用いて鍵が安全ならば, 弱いパスワードも記録された情報だけでは破れない
      • 「ちゃんと」しているかは「ちゃんと」した人にレビューしてほしい
    • 鍵を保持するものでも生パスワードを復元できない
  • デメリット
    • 鍵の管理のコストがかかる

1.1.15. その他

  • 方式を変更できるように実装しよう
    • 利用している暗号/ハッシュが脆弱だとわかるかもしれない
  • ユーザに弱いパスワード付けさせなければいい?
  • 管理者は, ユーザの入力したパスワードを処理するところなどで生パスワードを見ることができるよ.
    • 保存情報から復元できなくてもパスワードが漏洩するリスクはあるよ

1.1.16. 参考文献

[crypt]man 3 crypt Manpage of CRYPT
[CRYPTOGRAPHY_ENGINEERING](1, 2) CRYPTOGRAPHY ENGINEERING ISBN-13: 978-0-470-47424-2
[認証技術]認証技術 パスワードから公開鍵まで ISBN-13: 978-4274065163