← ブログに戻る

PINとパスワードの違いは桁数ではない: 6桁で足りる理由

PINは端末の中に封じられたまま外に出ず、パスワードは文字列そのものがネットワークを渡ってサーバーへ届く

情シスがパスキーを導入しようとすると、PINをパスワードと勘違いされて、この反応が返ってきます。

「6桁の数字だけ? 普通は英数記号混在で8桁以上だろう」

そして提案は差し戻される。私も一度これで引き下がりました。理由は単純で、当時は説明するのが面倒くさかったからです。それだけです。

この反論は、正しい常識を間違った対象に当てています。 パスワードの世界では桁数と文字種が防御力そのものです。その常識は正しい。ただしPINはパスワードと別の土俵にいるので、同じ物差しが当たりません。

多くの方がPINと聞いて思い浮かべるのは、Windowsのサインイン画面だと思います。同じ画面で切り替えられる。だから余計に同じものに見えます。ただ、この2つは入力欄が似ているだけで、入力した値の行き先がまったく違います。

Windowsのサインイン画面におけるPINとパスワードの行き先の違い。PINは端末内のTPMで検証されて止まり、サーバーには署名だけが届いて公開鍵のみが保管される。パスワードは入力値そのものがネットワークを渡り、サーバーにハッシュとして保管される

図の上段と下段の違いが、この記事で説明したいことのほぼ全てです。順に見ていきます。

パスワードは「桁数が全て」で合っている

まずパスワード側の常識を確認します。ここは疑う必要がありません。正しいからです。

パスワードは共有秘密です。入力した文字列がネットワークを渡ってサーバーに届き、サーバーはそれをハッシュ化して保管する。そして認証のたびに、同じ文字列が同じ経路を行き来します。毎回です。

ここから2つの性質が出ます。

  1. サーバー側のDBが漏れると、攻撃者は手元で好きなだけ試せる
  2. 1つのパスワードが漏れると、使い回した先まで連鎖する

決定的なのは1です。DBが漏れた後の総当たりに、回数制限はありません。攻撃者は自分のマシンでハッシュを回し続けるだけ。ログイン画面の「5回間違えたらロック」は、ハッシュを手元に持っている相手には何の関係もありません。完全に無関係。

だから長さを増やすしかない。8桁英数混在なら約62の8乗で、218兆通りです。回数制限が存在しない世界では、この数字だけが壁になります。他に何もありません。

「英数記号混在で8桁以上」は、無制限に試せる相手を想定した数字です。 ここを押さえておくと、次の話が通ります。

ただし「記号を混ぜろ」は、パスワード側でも既に否定されている

ついでに書いておきます。文字種の混在要求は、パスワードの世界でも現在は推奨されていません。NIST SP 800-63B は SHALL NOT、つまり最も強い禁止形でこう定めています。

Verifiers and CSPs SHALL NOT impose other composition rules (e.g., requiring mixtures of different character types) for passwords.

定期変更の強制も同じく SHALL NOT です。

Verifiers and CSPs SHALL NOT require subscribers to change passwords periodically.

理由は、利用者の反応が予測可能だからです。記号必須にすると Password1! が量産され、90日ごとの変更を求めると Password1!Password2! になる。文字種を増やしたつもりが、攻撃者にとっては探索範囲が狭まります。

効くのは4つです。長さ、漏洩パスワードのブロックリスト照合、保存方式、レート制限。 文字種はここに入っていません。つまり冒頭の「英数記号混在で8桁以上」は、PINに当てはめると間違いですが、そもそもパスワードに対しても古い基準ということになります。

PINは端末から出ない

パスキーのPINは、そもそもサーバーに送られません。

Microsoft の公式ドキュメントは、Windows Hello の PIN についてこう書いています。PINは端末にローカルで、どこにも送信されず、サーバーには保存されない。サーバーはPINのコピーを持っていない、と。

FIDO の CTAP 仕様も同じです。PINは認証器(YubiKeyやTPM)の中で検証され、外に出るのは pinUvAuthParam という認証パラメータだけ。PINそのものは境界を越えません。一度も。

つまり、サーバー側のDBが何回漏れても、そこにPINはありません。 あるのは公開鍵だけ。公開鍵は名前のとおり公開してよい情報で、そこから秘密鍵を導くことはできません。漏れても困らないものしか置いていない、ということです。

パスワードの最大の弱点だった「DB漏洩後の無制限総当たり」が、構造として発生しません。

桁数ではなく「桁数 × 試行回数」で見る

PINを破るには、その端末を物理的に手に入れて、そこで直接打ち込むしかありません。そして端末は、打たれた回数を数えています。

桁数だけを比べると6桁PINと8桁英数パスワードの差は約2億倍だが、試せる回数を掛けると6桁PINの突破確率は0.0008%、8桁英数はDB漏洩後に100%へ漸近して逆転する

数字にします。

組み合わせ試せる回数突破確率
パスキーの6桁PIN100万通り8回0.0008%
8桁英数パスワード(DB漏洩後)218兆通り無制限計算資源次第で100%に漸近

6桁は確かに100万通りしかありません。8桁英数の218兆と比べれば2億分の1。桁で負けているのは事実です。

ただし試行が8回で止まるなら、攻撃者が当てられる確率は 8 ÷ 100万 = 0.0008%。1万台の端末を盗んで、開くのは8台です。

一方、218兆通りのパスワードは、DBが漏れた瞬間に「時間をかければ必ず解ける」側へ移ります。GPUを並べれば、8桁英数は現実的な時間で落ちる。

比べるべきは、組み合わせの数と、それを試せる回数のセットです。 組み合わせの数だけを並べた比較は、片方の分母を見ていません。

「8回で止まる」の中身

この回数制限は運用ルールではありません。ハードウェアとファームウェアの実装です。ログイン画面のロックとは強度が違います。

PINの試行は二段構えで止まる。連続3回でCTAP2_ERR_PIN_AUTH_BLOCKEDとなりキーの抜き差しが必要になり、通算8回でCTAP2_ERR_PIN_BLOCKEDとなってリセット以外に復帰できずパスキーごと消える。キーを挿さないWindows HelloではTPM 2.0が32回でロックし失敗を忘れるのは10分に1回

セキュリティキー(FIDO2)の場合

FIDO の CTAP 仕様では、PINを3回連続で間違えると認証器が CTAP2_ERR_PIN_AUTH_BLOCKED を返します。この状態から先に進むには、キーを抜き差しして電源を入れ直す必要があります。マルウェアがユーザーの操作なしにキーをロックし続けられないようにするための設計です。

さらに、内部の pinRetries カウンタが0になると CTAP2_ERR_PIN_BLOCKED になります。こちらは抜き差しでは戻りません。

YubiKey の場合、この上限は合計8回です。8回間違えるとFIDO2アプリケーションがブロックされ、リセットするしかなくなる。そしてリセットすれば、そのキーに入っていたパスキーと指紋データは全部消えます。攻撃者から見ると、9回目に辿り着いた時点で対象そのものが消えている。総当たりの失敗ではなく、標的の消失です。

なお正しいPINを1回入れれば、カウンタは8に戻ります。日常的に打ち間違える人が困ることはありません。

Windows Hello の場合

こちらはTPMが数えます。TPM 2.0 は認可失敗が32回でロック。失敗を忘れるのは10分に1回だけ、という設定になっています。

ロック後の待ち時間も段階的に伸びます。最初の再起動後は1分。4回目で2分。5回目で10分。試すほど待たされます。

PINの最小長は4文字です。 6桁は仕様上の下限ですらありません。

では、パスワードも5回で止めれば同じでは?

ここまで読むと、当然この反論が出てきます。パスワード側も5回間違えたらIPをブロックすればいい、そうすれば英数字のみでも足りるのではないか、と。

筋は通っています。 NIST SP 800-63B も rate limiting を SHALL で要求しています。1アカウントあたり連続100回まで。むしろそれがあるからこそ「記号を混ぜろ」「90日で変えろ」といった複雑性ルールを撤廃してよい、というのが現在の主流の考え方です。方向として間違っていません。

ただし、担保にはなりません。 決定的な違いは、カウンタと秘密が同じ場所にあるかどうかです。

PINの場合、そのPINを試せる唯一の場所が、回数を数えている当人です。同じチップの中。物理的にそうなっています。

パスワードの場合、カウンタはログイン画面の前に立っているだけで、秘密そのものはその後ろのDBにあります。DBが抜かれた瞬間、攻撃者は玄関を通らずに済みます。 5回制限は入口を守っていますが、パスワードが破られる主な経路はそこではありません。

PINは秘密鍵とカウンタが同じ認証器チップの中に同居しているため迂回経路が存在しないのに対し、パスワードはカウンタがログイン画面の前に立つだけで秘密はその後ろのDBにあり、DB漏洩によって玄関を通らずに済んでしまう

NIST も同じことを書いています。

Offline attacks are possible when the attacker obtains one or more hashed passwords through a database breach.

だから同じ文書が、rate limiting とは別枠でソルト付き反復ハッシュでの保存を義務づけています。片方では足りないという前提の設計です。

IPという単位が攻撃者のコストになっていない

さらに、ブロックの単位をIPに置くこと自体に弱さがあります。

  • IPは替えが効く: 住宅用プロキシやクラウドを回せば実質無制限。IPv6なら /64 が1つで1800京アドレス
  • パスワードスプレー: 1アカウントに5回試すのをやめ、10万アカウントに1回ずつ試す。アカウント単位のカウンタにはほぼ引っかからない
  • CGNATの巻き添え: 1つのIPの裏に数千人いるので、厳しくすると正規ユーザーを締め出す。運用側は閾値を緩める方向に倒れる
  • 入口が1つとは限らない: Webフォームに制限があっても、API・モバイル用・レガシー経路・パスワードリセットのどれかが抜けていることがある

そして、回数制限が原理的に効かない経路が2つあります。

  • クレデンシャルスタッフィング: 他社から漏れた正しいパスワードを使う。1回目で通るので、回数制限は発火すらしません
  • フィッシング: 本人が入力して渡す。回数の問題ですらありません

PINはこの2つにも構造的に強いです。フィッシングでPINを聞き出しても、その端末が手元になければ何の価値もありません。パスワードは文字列だけで完結するので、どこからでも使えます。

まとめるとこうなります。rate limiting はオンライン総当たりを止めます。ただしパスワードが破られる主経路はオフライン総当たり・使い回し・フィッシングで、そこには効きません。必須ではあるが、それ単独では担保にならない。 同じ「回数制限」という言葉でも、ハードウェアが数えているのか、アプリケーションが数えているのかで意味が変わります。

そもそもPINは認証の主役ではない

ここが一番の誤解の元だと思っています。

パスキーの認証は、公開鍵暗号のチャレンジレスポンスで行われます。サーバーがランダムな値を送り、端末の中の秘密鍵がそれに署名し、サーバーが公開鍵で検証する。この署名が認証の本体です。秘密鍵は端末の外に出ません。

PINはこの署名を許可するための、端末内のスイッチです。 「今この端末を触っているのが持ち主か」を、端末が自分で確かめている。位置づけは生体認証(Touch ID、顔認証)と同じです。指紋の代わりに6桁を打っている。それだけです。

だから、パスキーの構成要素はこうなります。

  • 持っているもの: 端末の中の秘密鍵(取り出せない)
  • 知っているもの / 本人であること: PIN または生体(端末内で検証)

パスワードは「知っているもの」1要素で、しかもそれをネットワーク越しに送ります。パスキーは2要素で、どちらもネットワークに出ません。

PINとパスワードを桁数で比べるのは、家の鍵の「ギザギザの数」と、金庫のダイヤルの「桁数」を比べるようなものです。どちらも数が多いほど強くはなります。ただし「ギザギザ6個とダイヤル8桁のどちらが強いか」という問いには、答えがありません。役割が違うからです。

家の鍵はその扉の前まで来て1本ずつ差すしかないのに対し、金庫のダイヤルは設計図が漏れれば手元で全通り試せる。ギザギザ6個とダイヤル8桁のどちらが強いかという問いには答えがない

それでも正しい懸念はある

公平のために、PINが実際に弱い場面を書いておきます。

  • 肩越しの覗き見: 6桁は覚えやすい。だから見られたら再現されます。長いパスワードより現実的な脅威です
  • 端末ごと奪われた場合: PINを知られた状態で端末を持たれたら、8回のうち1回目で開きます。回数制限が効くのは「知らない攻撃者」に対してだけです
  • 推測されやすいPIN: 生年月日や 123456 は、8回の枠に十分収まります。桁を増やしても選び方が同じなら、結果は変わりません
  • PIN紛失時の復旧経路: 復旧がSMSやメールに依存していれば、そこが攻撃面になります

つまり、PINに対する正しい懸念は「桁数が少ない」ではなく、「観察されやすい」と「端末とセットで奪われる」の2つです。反論するときは、この2つは認めた上で話した方が通ります。

情シスが用意しておくべき一文

冒頭の場面に戻ります。「6桁の数字だけ?」と言われたときに返す内容を、1つにまとめるならこうなります。

パスワードの8桁は、DBが漏れたら無制限に試される前提の数字です。PINはサーバーに送られないので漏れる先が無く、端末を物理的に持っていても8回で止まります。守っている対象も、攻撃の経路も違います。

順序が効きます。まず認める。「長さが要る」という感覚は、無制限に試せる相手に対しては正しいからです。そのうえで、PINはその総当たりが成立しない場所にいる、と続ける。逆の順番で言うと、相手は自分の常識を否定されたと受け取って、内容が耳に入りません。

私が引き下がったのは、反論できなかったからではありません。一から説明する労力が、通したい提案に見合わないと判断したからです。公開鍵暗号の話から始めて、CTAPの回数制限まで説明して、それで納得してもらえる保証もない。黙って別の案を出す方が早いと思いました。

その判断自体は、たぶん間違っていません。間違っていたのは次です。同じことを言われるたびに同じ計算をして、毎回黙る側に倒れる。説明が面倒なら、面倒でなくなる長さまで畳んでおけばいい。 上の引用は、そのために置いてあります。

まとめ

  • パスワードは共有秘密でネットワークを渡り、サーバーに保管される。DBが漏れたら無制限に試せるので桁数が防御力そのもの
  • PINは端末から出ない。サーバーは公開鍵しか持たないので、総当たりの起点になるDBが存在しない
  • 比べるべきは「組み合わせ数 × 試せる回数」。6桁PINは8回で止まるので突破確率0.0008%
  • 止め方は運用ルールでなく実装。FIDO2は3回で要電源再投入、YubiKeyは合計8回でリセット必須、Windows HelloはTPMが32回でロック
  • そもそもPINは認証の主役ではない。認証の本体は秘密鍵の署名で、PINはそれを許可する端末内のスイッチ
  • 「パスワードも5回で止めれば同じ」は筋は通るが担保にならない。カウンタはログイン画面の前に立っているだけで、秘密はその後ろのDBにある。DBが抜かれたら玄関を通らずに済む
  • 正しい懸念は「覗き見」と「端末ごと奪われる」の2つ。桁数はそこに入らない。反論ではここを認めた上で話す

より実装寄りの話(CTAPのエラーコード、pinUvAuthToken の流れ、TPMのanti-hammering の実装値)は、Qiitaに別記事として書いています。

パスキーが「そもそもフィッシングサイトでは押しても反応しない」という別の性質については、あなたのパスキーは、フィッシングサイトでは押しても反応しません に書きました。

参考