# password.es のどこが悪かったのか、そしてもう直った話

> 物事はこうあるべきだと一日じゅう言っている場所は、自分がそうしていなかった時のことも語らなければならない。自分の家で見つけたものを、数字とともに。

2026-08-31 · David Carrero · password.es
Original: https://password.es/ja/blog/password-es-no-dokoga-warukatta-ka/

---

このブログには、物事はこうあるべきだと説明する記事が十二本ある。長さは記号より重い
こと、パスワードマネージャーは便利さではなく唯一その規則を守れる手段であること、パ
ーセントは何も語らないこと。

それを書くのは簡単だ。居心地が悪くなるのは、同じ物差しを自分のサイトに当てたとき
だ。**当ててみたら、三つ悪いところがあった。** それを暴いた数字ごと、まるごとここ
に書く。自分の当たりだけを公開するセキュリティのサイトは、かなり値打ちが落ちるから
だ。

## チェッカーは入力中に固まっていた

チェッカーは [zxcvbn](https://github.com/dropbox/zxcvbn) であなたのパスワードを解析
する。大文字を数えるのではなくパターンを探すライブラリだ。よくできていて、その代わ
り代償がある。**一気に、ページを描くのと同じスレッドの上で走る**のだ。走っているあ
いだ、ブラウザーは他に何もできない。

その代償は長さとともに急に大きくなる。サイトが配っているのと同じ束で、しかも人が実
際に打つ種類のパスワード——単語、西暦、`a` の代わりの `@`——で計測した。

| 長さ | 一回の実行 |
|---|---|
| 16 文字 | 45 ms |
| 20 文字 | 121 ms |
| 32 文字 | 273 ms |
| 64 文字 | 843 ms |
| 128 文字 | 3,621 ms |

ここまでは普通だ。問題は、それを何回起動していたかだった。

入力欄には `input` と `keyup` という**二つ**の別々の監視が付いていた。普通のキーは
その両方を発火させる。つまり一文字打つたびに、完全な解析が**二回**走っていた。16 文
字のパスワードで 90 ms、32 文字なら半秒だ。

しかも止めるものが何もなかった。タイマーも、長さの上限も、別スレッドもない。二十文
字を超えたあたりから、ブラウザーが解析にかける時間のほうが、あなたが次のキーを押す
までの時間より長くなる。打鍵は二度と空にならない待ち行列に積み上がり、**入力中にペ
ージが反応しなくなっていた**。長いパスワードを貼り付ければ数秒固まった。

直し方は小さな変更が二つ。`keyup` の監視を外した。`input` だけで入力も貼り付けも削
除もマネージャーの自動入力も拾えるからだ。見えるものは何ひとつ変わらないまま、仕事
の半分が消える。そして 150 ミリ秒の待ちを入れた。打っているあいだは何も解析せず、手
を止めた瞬間に解析する。それに気づくほどゆっくり打つ人はいない。

結果は同一だ。`Barcelona1992$` は今も同じことを言う。「barcelona」は辞書にあり、1992
は西暦に見え、一秒とかからず落ちる、と。

## 説明文は十五の言語で文の途中で切れていた

こちらはもっと間抜けで、もっと恥ずかしい。

検索結果でタイトルの下に出る一文——メタディスクリプション——が、チェッカーの**十八言
語のうち十五で切れていた**。無事だったのはスペイン語、韓国語、日本語だけ。誰かがど
こかで長さを理由に刈り込み、単語の途中で切り、その後だれも見なかった。

三つの言語では、切れ目がちょうど特殊文字の真ん中に落ちた。つまり Google に出してい
たのはこれだ。

| 言語 | 配っていたもの | 本来 |
|---|---|---|
| ポルトガル語 | `…datas e padr&o` | `padrões` |
| トルコ語 | `…arıyor ve ger&cced` | `gerçekten` |
| ベトナム語 | `…chúng tôi tra mật kh&#` | `mật khẩu` |

目を引くのはその場所だ。**サイト全体でいちばん成果の出ているページ**である。チェッ
カーはジェネレーターよりはるかによく機能していて、しかも壊れた説明文のままそうして
いた。十五本とも埋めた。

ついでに韓国語・日本語・ベトナム語では、ブランドをタイトルの先頭から末尾へ移した。
検索結果ではドメインが別に表示されるのだから、「password.es ·」で始めるのは、いちば
ん重い場所を捨てているだけだった。

## 一億分の一の偏り

ジェネレーターは各文字を `crypto.getRandomValues()` で選ぶ。ブラウザーのまともな乱数
源だ。ところが、その巨大な数を「アルファベット上の位置」に変えるのに剰余を使ってい
た。ここに古典的な罠がある。2³² は 83 の倍数ではないので、**アルファベットの先頭の
位置が、末尾より ほんのわずかに よく出ていた**。

どのくらい「わずか」か。最大 89 文字のアルファベットで、一億分の一の桁だ。何も変わ
らない。あなたのパスワードを測れるほど弱くはしない。まったく近づきもしない。

それでも直した。三行だ。4,294,967,296 通りのうち余る 45 個を捨てて引き直す。パスワ
ードのサイトで、取り除くのがその程度で済むのに「無視できる」は偏りを残す理由になら
ない。

## 足りなかったもの——約束をブラウザーに守らせること

[あなたのパスワードはここから出ない](/ja/blog/naze-password-wo-okuranai-no-ka/)と
説明する記事がまるごと一本ある。本当のことだったが、それでもこちらの一文にすぎなか
った。注入されたスクリプトが別のことをするのを、技術的に妨げるものは何もなかった。

いまはどのページもコンテンツセキュリティポリシーを積んでいる。効くのは二つ。

- **構築時にページになかったスクリプトは動かない。** 正規のスクリプトはそれぞれ指紋
  で署名されている。注入されたものは一致せず、ブラウザーが実行を拒む。
- **`connect-src 'none'`。** このサイトは JavaScript から一度もネットワーク要求をし
  ない。それをいまはブラウザーが強制する。いつか何かがあなたの打った文字をどこかへ
  送ろうとしても、外へは出ない。

約束は宣言をやめ、規則になった。

## いまも直っていないこと

**8月31日の追記。**この節の三つは、この記事が出たその日のうちに直りました。十五の言語は本当のエンジンを説明するようになり、二つの尺度は一つになり、チェッカーのよくある質問が記号の件を説明しています。それでも書いたまま残します。何が間違っていたかの記録は、非の打ちどころのないサイトの写真より値打ちがあるからです。

この記事が席を得るのはここからだ。

**十五の言語がいまだにチェッカーを古いエンジンとして説明している。** そのページの文
章は、PasswordMeter の古典的ロジックを再現している、と言う。もう違う。あのエンジン
は `Password1!` を「非常に強い」と呼び、五語のパスフレーズを落としたから取り替えら
れた。言うべきことのちょうど逆だ。スペイン語・韓国語・日本語は更新済み、残る十五は
そのままだ。

**同じ家に二つの尺度がある。** トップページはビット数でパスワードの強さを決め、チェ
ッカーは破るのにかかる時間で決める。別々の基準なのに、どこにも書いていない。

**ジェネレーターとチェッカーは同じ記号を数えていない。** 一方は 27 を使い、もう一方
は 33 を仮定している。差は小さいが、ある。

三つとも重大ではない。三つとも負債であり、誰かに見つけられるのを待つより、ここに書
かれているほうを選ぶ。

## このバージョンの変更履歴

リポジトリが公開ではないので、変更履歴はここに全部書く。**0.2.0**、2026 年 8 月 31
日。

**追加。** ページごとのコンテンツセキュリティポリシー。各スクリプトの指紋つき。保存
したパスワードがどこにあるかの記事を十八言語で。何を書くかを決め、空になったら何も
公開するなと命じる編集キュー。

**修正。** チェッカーの説明文。十五言語で文の途中で切れ、うち三つは文字が半分に割れ
ていた。入力中のタブの凍結。抽選の偏り。そして前の記事に欠けていた写真。

**変更。** 韓国語・日本語・ベトナム語でのチェッカーのタイトル。デプロイ。いまは構築
済みのサイトが存在してから起動する。一分前ではなく。そしてベトナム語・ヒンディー語
・アラビア語の翻訳は、いちばん弱いままではあるが、公開を止めなくなった。

---

*この記事の数字は推定ではなく実測である。zxcvbn の時間はサイトが配るのと同じ束と、単
語や置き換えを含むパスワードで計測した。抽選の偏りは 32 ビット整数の 4,294,967,296
通りの値の上で計算した。チェッカーのエンジンはオープンソースの
[zxcvbn](https://github.com/dropbox/zxcvbn)。*
