Upgrade to Pro — share decks privately, control downloads, hide ads and more …

djangocongressjp2023_password_hash

bungoume
October 06, 2023

 djangocongressjp2023_password_hash

bungoume

October 06, 2023
Tweet

More Decks by bungoume

Other Decks in Programming

Transcript

  1. 2 自己紹介 ❏ Yuri Umezaki (@bungoume) ❏ 検索API (Elasticsearch, Django)

    ❏ OAuth認可 API基盤 ❏ アクセスログ分析
  2. 12 オフライン攻撃想定 MD5をGeForce RTX2080 (40GH/sec)で計算した場合の時間 8桁の英大小文字+数字で1時間 • 2023最新のRTX 4090は150GH/secなので更に約¼ ◦

    9桁の英大小文字+数字が約1日 2020 パスワード総当り 必要時間表 https://www.response-it.co.uk/news/2020/9/2/how-long-does-it-take-to-crack-your- password https://openbenchmarking.org/test/pts/hashcat
  3. 19 • Argon2 • pip install argon2-cffi • settings.py に以下の設定を入れればOK

    ◦ (先頭のものが利用されます。2つ目以降は移行用) おすすめの設定
  4. 23 • 計算コストを増やす目的 • 何度も繰り返しハッシュ化し元データ推測を困難にする • 数十万回行うことも • ストレッチ回数: iterations

    用語: ストレッチング mypassword 91dfd9dd… fabe5482… 83d5743b… ハッシュ化 ハッシュ化 ハッシュ化
  5. 25 • auth_userのpassword field(char 128)に格納 • $区切り • 先頭はハッシュ方式 •

    その後、パラメータとハッシュ(詳細は各関数に異なる) 例: [タイプ]$[ストレッチ回数]$[ソルト]$[ハッシュ] Djangoにおけるパスワードデータ pbkdf2_sha256$360000$dNhx87pKlB9E$xKRyAEunJkChipeBH aIbSNipBUOSTvUcqMUFrvz9UEI=
  6. PBKDF2 28 • Djangoのデフォルト方式で、よく利用される • ライブラリ不要 • iterationsを増やすのが容易 • NIST

    FIPS-140 で推奨 [タイプ]$[ストレッチ回数]$[ソルト]$[ハッシュ] pbkdf2_sha256$720000$FkxESIA1MrrH$EXYJuJLVXjJ8A+MLGKJ9bfQ2HWr1mRhcB2tlSHyWiG4=
  7. 29 イテレーション回数はバージョン更新ごとに増加 v1.4-1.6: 10000 ->v1.7: 12000 … -> v2.0: 100000

    -> v2.1: 120000 … -> v4.2 600000 -> v5.0 720000 https://docs.djangoproject.com/en/dev/internals/howto-release-django/#new-stable-branch-tasks > New stable branch tasks Increase the default PBKDF2 iterations in > django.contrib.auth.hashers.PBKDF2PasswordHasher by about 20% PBKDF2のイテレーション数
  8. SHA256+bcrypt 30 • Blowfishという古い暗号化方式を利用 • ハードウェア化が難しいとされる • iterationsで計算量を増やすことが可能 ◦ 必要メモリ量の調整はできない

    • BCryptPasswordHasherはパスワードを72文字で切り捨て • PHPなどの標準方式 • 利用事例も多い [タイプ]$[タイプ]$[ストレッチ回数]$[ソルト(22文字)][ハッシュ(31文字)] bcrypt_sha256$$2b$12$XScV8pd5i/ERqlLx2Q1Ipu2qBGUlc1HorN5Y4mEOurNlt/K6/UC.u
  9. scrypt 31 • Django4.0から利用可能 • メモリ使用量を増やし、ハードウェア化を難しくした設計 • bitcoinフォークのLitecoinで利用されているらしく、既にある程度 ハードウェア化されている ◦

    TMTO(Time-Memory Trade Off)等でハードウェア化を防ぎきれなかった ◦ 選択肢として致命的な問題があるわけではなさそう [タイプ]$[メモリ,CPUコスト]$[ソルト]$[ブロックサイズ]$[並列数]$[ハッシュ] scrypt$16384$AHnJwIHTDWiUrcEelaZ3i6$8$1$upF27cH+BRCe8QFnTNkby7eN3RuDw/GJslociOjopz PIZM4ebz2GPnHLBtZl6ZhRR28p54pL8cm5mPcvBSodcg==
  10. Argon2 32 • Password Hashing Competition(2015.7) 勝者 • メモリ使用量を設定するパラメータがある •

    Djangoで利用にはサードパーティのライブラリが必要 ◦ pip install argon2-cffi [タイプ]$[タイプ]$[バージョン]$[m=メモリコスト],[t=タイムコスト],[p=並列数]$[ソルト]$[ハッシュ] argon2$argon2id$v=19$m=102400,t=2,p=8$S0JrY1YzVDYwTjg0dlE1UjRvUTllSA$bDLYCv6H6wZ mu6ZWjEby0twmI27SApnFEyjyrszNJ9E
  11. Argon2 33 • argon2i サイドチャネル攻撃耐性 • argon2d GPUを使った攻撃に対する耐性 • argon2id

    いいとこ取り 今はargon2idが推奨 Djangoは3.2よりargon2iからargon2idに変更 (PHPは7.2でargon2iを導入、PHP7.3でargon2idをサポート)
  12. 速度比較 34 設定値 1回あたり Mem PBKDF2 iterations = 720000 (v5.0

    default) 390 ms 0.0 MiB SHA256+bcrypt rounds = 12 (default) 250 ms 0.2 MiB scrypt N=2^14(16 MiB), r=8, p=1 (default) 47ms 16.0 MiB scrypt N=2^14(16 MiB), r=8, p=5 (OWASP) 220ms 16.0 MiB Argon2id t=2, m=102400, p=8 (default) 56 ms 100.4 MiB Argon2id t=2, m=19456, p=1 (OWASP) 33ms 19.0 MiB ## python version: 3.11.4 ## python compiler: Clang 14.0.0 (clang-1400.0.29.202) ## cpu model: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
  13. 速度比較(2018の資料, CPUが違います) 35 設定値 100回 (秒) 1回あたり SHA1+Salt 0.0074 0.01

    ms PBKDF2 iterations = 100000 12.6987 127 ms SHA256+bcrypt rounds = 12 38.6854 387 ms Argon2 m=512, t=2, p=2 0.1901 2 ms ## python version: 3.6.5 ## python compiler: GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.1) ## cpu model: Intel(R) Core(TM) i5-4250U CPU @ 1.30GHz
  14. 36 1. Argon2id 2. Argon2idが使用できない場合はscrypt 3. 今使ってる場合はbcrypt 4. FIPS-140 準拠が必要な場合PBKDF2

    それぞれ安全な設定値で使うこと (+多層防御としてペッパーの追加を検討) OWASPの推奨値
  15. hashcat 41 • 世界最速を謳うパスワードクラッカー • https://hashcat.net/hashcat/ • OSS (MIT) •

    GPU, FPGAなど利用可能 • 200以上のhashに対応 ◦ Django (SHA-1) ◦ Django (PBKDF2-SHA256) 注: パスワードクラックを推奨するものではありません。
  16. 使い方 42 $ sqlite3 db.sqlite3 "SELECT password FROM auth_user;" >

    django_pass.txt $ hashcat -m 10000 -a 0 django_pass.txt 10-million-password-list-top-10000.txt -O
  17. 45

  18. 48 オフライン攻撃が容易な箇所は注意が必要 • 秘密鍵 ◦ v2のsshkeyやed25519はKDFラウンド数指定可能(-a) • zip ◦ stretchなし

    or hmac-sha1×1000ラウンド • Word, Excel ◦ 2007以降は50000〜100000ラウンド DBだけでなくファイルも注意 参考 https://www.slideshare.net/herumi/ss-57319518#4
  19. パスワードハッシュで出来なくなること 49 • チャレンジレスポンス型認証 ◦ CHAP ◦ CRAM-MD5 ◦ DIGEST-MD5

    • クライアントでワンタイムnonceを使ってハッシュを計算 ◦ サーバー側でも生passwordが必要
  20. まとめ 51 • DjangoのパスワードハッシュはArgon2を選ぶと良い ◦ 標準の設定(PBKDF2)でも全く問題はない ◦ Djangoのパスワードハッシュアルゴリズムの変更は容易 • パスワードハッシュ計算は以前より時間がかかる

    ◦ API用などで都度検証する実装の場合、性能劣化要因になっている可能性 • 利用者は強いパスワードを使うこと • 昔から動かしているサービスはハッシュ移行を検討 • Password management in Django に詳細