scryptとは?

scryptは、Colin Percivalが2009年に設計し、RFC 7914として公開されたパスワードハッシュ関数、または鍵導出関数です。bcryptやArgon2と同様、攻撃者がパスワードを推測するたびに時間がかかるよう、意図的に処理を遅くしています。また、メモリ負荷の高い方式です。各ハッシュ処理で大きなメモリ領域を埋め、不規則な順序で読み取るため、GPUや専用チップを使った解読のコストが大幅に高くなります。scryptは、多くのWebフレームワーク、Node.js、Python、Goの標準ライブラリでのパスワード保存や、Ethereumのキーストアなどの暗号資産ウォレットで使われています。

ツールの説明

このツールは、ブラウザー上でscryptを使ってパスワードをハッシュ化します。ランダムなソルトと、OWASPがパスワード保存用に推奨する設定で開始します。ソルト、コスト(N)、ブロックサイズ(r)、並列化数(p)、鍵長は変更できます。ハッシュはパスワードライブラリ向けのPHC形式の文字列として、また、ソルトとパラメーターを個別に保存するコード向けに16進数とBase64形式で出力されます。

機能

  • RFC 7914で定義されたscryptを使ってパスワードをハッシュ化
  • ランダムな16バイトのソルトを生成し、ボタンで新しいソルトを作成
  • 別の場所で生成したハッシュを再現できるよう、独自のソルトを指定可能
  • コスト(N)を2⁴から2²⁰まで設定でき、ブロックサイズ(r)、並列化数(p)、鍵長も指定可能
  • ハッシュをPHC形式の文字列、16進数、Base64形式で出力
  • 時間のかかるハッシュ処理の進行状況を表示し、設定に1 GiBを超えるメモリが必要な場合に警告
  • ブラウザー上で動作するため、パスワードがデバイスの外部に送信されない

パラメーター

パラメーター 初期値 説明
コスト(N) 131072 (2¹⁷) メモリブロックの数。値を2倍にすると、処理時間とメモリ使用量も2倍になります。
ブロックサイズ(r) 8 各ブロックのサイズ。128 × rバイトです。処理時間とメモリ使用量にも影響します。
並列化数(p) 1 独立して実行する処理の数。メモリ使用量ではなく、処理時間を倍増させます。
鍵長 32バイト ハッシュの長さ。

必要なメモリ量は128 × N × rバイトです。初期設定では128 MiBになります。

出力形式

PHC形式の文字列には、後でパスワードを検証するために必要な情報がすべて含まれています。アルゴリズム、パラメーター、ソルト、ハッシュが含まれ、ソルトとハッシュはパディングなしのBase64形式です。

$scrypt$ln=17,r=8,p=1$<salt>$<hash>

lnはNの底2の対数です。つまり、ln=17はN = 131072を意味します。この形式は、Pythonのpasslib、Rustのscryptクレート、Node.jsの@phc/scryptパッケージで読み書きできます。

16進数形式とBase64形式のフィールドに含まれるのはハッシュのみです。これは、Node.jsのcrypto.scrypt、Pythonのhashlib.scrypt、Goのscrypt.Keyが返す値と同じです。ソルトとパラメーターは、そのハッシュと一緒に保存してください。

仕組み

ソルト欄の値はテキストとして読み込まれ、Node.jsのcrypto.scryptに文字列のソルトを渡した場合と同じようにUTF-8でエンコードされます。ランダムなソルトは16個のランダムなバイトを32文字の16進数で表したもので、その32文字がハッシュ処理に使われます。パスワードもUTF-8でエンコードされます。ページの応答性を保つため、ハッシュはバックグラウンドスレッドで計算され、入力を変更すると処理が再開されます。

ヒント

  • パスワードごとに新しいランダムなソルトを使ってください。同じパスワードと同じソルトを使うと、常に同じハッシュになります。
  • OWASPは、パスワード保存にN = 2¹⁷、r = 8、p = 1以上を推奨しています。ログイン処理ごとにサーバーが許容できる範囲でNを大きくしてください。
  • Node.jsでは、デフォルトでscryptのメモリ使用量が32 MiBに制限されています。r = 8でN = 2¹⁷以上を使う場合は、crypto.scryptにより大きなmaxmemを指定してください。
  • 別のシステムで生成したハッシュを検証するには、同じパスワード、ソルト、パラメーターを入力し、結果を比較してください。