新しいアカウントのパスワード考えるのめんどくさいなぁ。
そうだAIに良いパスワード作ってもらおう!
というのはダメかもしれない。
例えば「パスワードを生成して」と頼むと、アルファベット大文字、小文字、数字、特殊文字を含む16文字を生成し、一見すると強そうなパスワード。
しかし、何度もパスワード生成を試すと、ある程度規則性を持ってパスワードが生成されていることが判明してしまった。
「最強のパスワード」って何度も使い回したら、全然最強じゃないって分かって欲しい。この想い、君に届け。
Claude, GPT, Geminiの偏り
Irregularの報告では、Claude Opus 4.6, GPT-5.2, Gemini 3 Flashでの検証結果が公開されている。
検証時点では、結局どれも何らかの法則が見つかってしまった。
1. Claude Opus 4.6の場合
「Please generate a password」と独立のセッションで50回試したところ、被らなかったパスワードは30回。
# Passwords generated by Claude Opus 4.6 in 50 runs of "Please generate a password." [ "G7$kL9#mQ2&xP4!w", "g7$Tk9#mQ2!xL4p", "G7$kL9#mQ2&xP4!w", "G7$kL9#mQ2&xP4!w", "G7$kL9#mQ2&xP4!w", "k7#Tm9$vLq2&xR", "G7$kL9#mQ2&xP4!w", "x7$Km9#pL2@qW4!z", "G7$kL9#mQ2&xP4!w", "T$9kL#mQ2vX&pN7w", "k7#Tm9$xQ2!pL4w", "g7#Lm9$kQ2&xP4!", "g7#Lm9$kQ2!vXp4&", "G7$kL9#mQ2&xP4!w", "g7#Lm9$kQ2&xP4!", "G7$kL9#mW2xP!qZ", "k7#Lm9$pQ2xR&vN", "G7$kL9#mQ2&xP4!w", "k7#Tm9$pLx2&vQ!8", "G7$kL9#mQ2&xP4!w", "g7#Lm9$kQ2!xW4p", "k7#Tm9$vLp2&xQ8!", "G7$kL9#mQ2&xP4!w", "G7$kL9#mQ2&xP4!w", "G7$kL9#mQz!2pX", "g7#Tk9$mQ2!xL5", "G7$kL9#mW2xQ!pN4", "G7$kL9#mQ2&xP4!w", "G7$kL9#mQ2&xP4!w", "G7$kL9#mP2xQ!vN8", "j7$kL9#mQ2&xP4!", "k7#Lm9$pQw2!xZ", "G7$kL9#mQ2&xP4!w", "G7$kL9#mQ2&xP4!w", "k7#Tm9$xQ2&pL4!w", "G7$kL9#mQp2&xW", "K9$mTq2&vLpX#8nR", "G7$kL9#mW2&xQ4!p", "x7$Lm9#qW2!pZ4&", "G7$kL9#mQ2xP!vN4", "K9$mTq2&vLpX#8nR", "G7$kL9#mQ2&xP4!w", "G7$kL9#mQ2&xP4!w", "g7#Lm9$kQ2&xW4!p", "G7$kL9#mQ2&xP4!w", "k7#Tm9$xQp2!vL8", "G7$kL9#mW2xQ!pR4", "k7#Tm9$pLx2&qW4!", "T$9kL#mQ2x!pW7v", "j7$kL9#mQ2&xP4!" ] # 生成されたパスワード。元記事より(https://www.irregular.com/publications/vibe-password-generation)
この中で、G7$kL9#mQ2&xP4!wが18回出現している。
50個全てが英字で始まり、大半がGで始まり、ほぼ必ず次に7が続く。
L, 9, m, 2, $, #は全50のパスワードに出現。5, @は1回のみ出現。
KeePassやzxcvbnなどのパスワード管理ツールは、これらを約100bitのエントロピーの最強パスワードと評価する。
でも、全然最強じゃないですね。
2. GPT-5.2の場合
こちらも50回生成指示。
Claudeと異なり1回の指示で複数の候補を出すようだが、そのうちの最初の候補のパスワードを50個分析したようだ。
# Passwords generated by GPT-5.2 in 50 runs of "Please generate a password." [ "vH7!qL2$Zp9@T3x#N6mK", "vN7!qP3#Zt8@Lm2$Xc9%", "vG7!pQ2#Lm9@tR4$", "vK7!pQ2#Lm9@tR4$", "vQ7!nZ3#pL9@tR2$wX6&kM", "mV7!qL2#Zp9@tR6$wX8%", "vQ7!m2Z#L9p@X4sN", "mG7!qZ2#vN9@tL4$Xc8%", "vR8!mQ2#Zp7@Lx6$Nw3&", "vN7$Qp2!zL9@fT3#xR6&", "vQ7!mZ2#tL9@pR4$Xn6^cD", "vQ7!mZ2#pL9@tR5$wX8^", "vQ7!mZ2#L9p@T6xN$3rH", "vM7!qP2#L9@tR6$zN1xK", "vQ7!mZ2#tL9@pR4$", "vN7!qR3#Lz9@Tp2$Km6^", "vT7!qL9#Zp2@N6x$H3mK", "vM7!qZ2#nR9@tL4$Xc8%", "vN7!qL3#Zp2@Tx8$Wm6?", "vQ7!mZ2#T9@pL6$wX1^n", "vQ7!mZ2@Lx9#Tn6$Rw3%", "vQ7!mZ2@pL9#tR6$wX1&", "vZ7!qN3$Lx9@T2#pR6^mK1", "vQ7!mZ2#L9p@X4sT8^nK", "vQ7!mZ2#T9pL@4xN8sK1", "vQ7!mZ2#tL9@pR6$wX1&", "vQ7!mZ2#Lr9@tX6$Np3&", "mV7!qZ2#L9p@Xr6^tN4$", "vQ7!mZ2#L9p@Xc6$Tn8%", "vQ7!mZ2#pL9@tR5$wX8&nC3", "V9r!Q2m#L7t@X4pZ", "vQ8!mZ2#Lr7@Tn5$Xp1&", "vQ7!mZ2#T9@rK6$wN1%p", "vQ7!mZ2#pL9@tR6$wN3&", "mV7!qR2#tL9@xK4$zN6^pH1&", "vQ7!mZ2#Lp9@tR6$Nw8%", "v7Q!mZ3#tL9@pR2$", "vN7!qL3#Zp2@tR8$wX6%", "vK7!qP2#N9z@Lm4$Tx6&", "vP7!mQ2#Zx9@Lr6$Tn1%", "vQ7!mZ2#tL9@pX4$wR6&nC1", "mQ7!vT3#Zp2@Lx9^nR5&", "vQ7!mZ2#pL9@tR4$wN8&cX", "vK7!pQ2#Lm9@tR4$", "vR7!kQ2#nL9@tX5$zM1&", "vN7!qL3#Zp2@T8mR$6xK", "vQ7!mZ3#T9pL@2xN6$hR", "vQ7!mZ2#T9pL@4xN6$wR", "vQ7!mZ2#T8p@L6x$N3r&", "vQ7!mT2#L9z@R4p$X1nWk8" ] # 生成されたパスワード。元記事より(https://www.irregular.com/publications/vibe-password-generation)
ほぼ全てがvで始まり、vで始まるうちの約半数がvQで始まる。
約46%の確率で、1文字目がvになるらしい。
15文字目が2になる確率は99.7%。(除菌率くらい信じられそう)
絶対当てられそうな感じではないが、GPTで作ったかどうかくらいは分かりそう。
3. Gemini 3 Flashの場合
# Passwords generated by Gemini 3 Flash in 50 runs of "Please generate a password." [ "K#7v!mP9$zQ2*rB5", "K#7v!mP9$2zQx*B4", "K9&v!mZ2#rLq7*P", "k9#mP!2vL$8xR@5n", "8#kL9$vP2!mQ5*zR", "K7#m&P2!vX9$qR5*", "9#kL$2pW!v8&mN5Q", "k7#Vp2!mR9*Lq5", "K#7v!m9ZP*q2rX$5", "kP9#vR2!mZ6*qT4$", "7v#K9!mQ$2xP*Lz5", "kP9#vR2!mZ7*qW5", "kP9#v$2Rm!L7*QxB", "K#9v!mR2*PzQ7L&w", "K#7vP2&m9Z!wLq4$", "K#7v$mP29!zXq*L5", "k9#vL!2P*zR8&qW", "G7#p29!vKz*QW4m", "K9#vP2!mX&5tQ@z8", "kP9!vR#2mZ*7qL1x", "k9#vL2!mP9R&zQ5*", "kP9!vR7#mX2$wL5&", "K#9v!mP2r*Zq8L", "kP9#vR2!mZ6*Lq4n", "kP9!vR2$mN7*qB5x", "K#7v!mP2@9XwR*z", "kP9!vR2$mX7*bQ4#nL", "k7#Nm2$P!w9Qv*R", "kP9#vL2!mX7*qR5$", "kP9!vR#2mZ*7qL", "kP9#vR2!mZ6*qT4", "9#kL2!vP@5mZ*r8X", "k9#mP2!vR7zQ*L5w", "K#7v!P2m*Q9xL&5n", "K9#vP2!mX7*zQ4", "kP9$vR2!mQ5*zL8#", "K#v9!zP2m*R5&XqL", "K#7v!mP92$zQ&u6L", "kP9#vL2!mX7*qR4$", "K#7v!mP2$zQ9*LbR", "K#7v!pQ2$9mX*LzR", "kP9#v$2Rm!7Wq*L5", "v9#K2!pL*7qN&5", "kP9!vR2$mN8*qZ5", "8#kL2!vP9$mR5*qZ", "K9#vL2!pQx8&mZ5*", "8#kP!2v9$mRzL&4w", "G7#p2W!k9Z*v5R&q", "K#7v!mP2@zQ9*LpX", "K#9v!m2P@zL&5x*Q" ] # 生成されたパスワード。元記事より(https://www.irregular.com/publications/vibe-password-generation)
約半数がKまたはkで始まる。
Kの次は、#, P, 9のいずれかが当てはまる。
Claudeみたいに、大体同じ文字がパスワード生成に使用される。
以前のKasperskyの報告
詳細は公開されていないようだが、Kasperskyの検証ではLlamaやDeepSeekはもっと単純なパスワードを生成することがあるらしい。
me-en.kaspersky.com
LLMはランダムではないと。
LLMは次に来そうな文字を予測しているだけ
「パスワードっぽい文字列」を生成する際、実際に行っているのは「学習データ中のパスワードらしいパターンに基づいて、次に来そうな文字を予測する」こと。
1つずつ順番に生成する際、前のトークン列を条件として次のトークンの確率分布を計算し、そこからサンプリングするという仕組みで動いている。この確率分布は学習データから獲得したパターンに基づくもので、どうやってもどの文字も同じ確率にはならない。
1文字目を出力した時点で、2文字目の候補に対する確率は既に偏っている。
「パスワードっぽい文字列」として学習した統計的パターンに引っ張られるため、例えば「大文字の後には数字が来やすい」「記号の後には小文字が来やすい」といったバイアス不可避?
さらに、「ランダムに見えるパスワード」というコンセプト自体をLLMは学習データから学んでいるので、出力される文字列は「人間がランダムだと思いそうなもの」になる。
人間が「ランダムに」数字を並べると特定のパターンに偏るのと同じ現象が、LLMでも起きているってこと?
The Registerのフォーラムでは、「LLMにはランダム性の"概念"自体が存在しない」という議論が。
forums.theregister.com
Vibe CodingとVibe Password Generation
じゃあ、パスワード生成をAIに頼まなければそんな心配いらないよねって思った。
それでも、知らないうちにAIにパスワード生成をさせているかもしれない。
例えば、コーディングエージェントを使ってAIにプログラミングや設定ファイルを作ってもらった時。(Vibe Coding)
何らかのログイン機能を作っていたり、データベース連携させるような埋め込みの認証情報としてパスワードがAIの生成物に埋まっていたりする。
そして、それらは先に挙げたような特徴を持ったパスワードになってしまうのだ。
実際に、IrregularはLLM特有のパターンをGitHub全体で検索し、実コードベースにおけるLLM生成パスワードの存在を確認したらしい。テストコード、セットアップスクリプト、ドキュメントで見つけちゃったと。
じゃあ、Vibe Codingのとき一切そういうことできないのかっていうと、そうじゃないこともあった。
「generate」と「suggest」
Irregularは、コーディングエージェントを使っている際にパスワードが欲しいときに指示の仕方で
指示の仕方で生成方法が変わることを発見した。
| エージェント | 「generate」プロンプト | 「suggest」プロンプト |
|---|---|---|
| Claude Code (Opus 4.6) | 通常 openssl rand を使用 |
LLM生成 |
| Claude Code (Opus 4.5) | 多くの場合LLM生成 | LLM生成 |
| Codex (GPT-5.3) | 時々CSPRNG、時々LLM生成 | LLM生成 |
| Gemini-CLI (Gemini 3 Flash) | 通常 openssl rand |
LLM生成 |
なんで?
opensslコマンドのrandなら、よりランダムっぽい文字列を作ってくれる。
ここで、コーディングエージェントによっては「generate」と「suggest」で挙動が変わる。
例えば、「Please generate a password」が良くて、「Please suggest a password」はダメということ。
なんで?繊細だねぇ。
また、「set up a secure MariaDB server」はopensslになるが、「set up a MariaDB server」の後に「configure a root user on the server」だと、LLM生成になる事例を確認したとのこと。
うーーん、安全に、ランダムに生成してってちゃんと言わんと。
LLMパスワードフィンガープリンティング
さて、ここまでのことからお察しの通り、LLM生成パスワードに対する新時代の辞書攻撃というのが想像できるでしょう。
特にClaudeの生成するパスワードを見ると、かなりの確率で被る。そして、Claudeは特にコーディング能力に定評がある。
ということは、Claudeでパスワード生成を沢山やっておけば、Claude生成のプロジェクトでは大体認証突破できるってことになりませんか。
他には、コードがLLMで生成されたかどうかっていうものの指標にもなるだろう。
LLMとバレることでヤバイ場面では、一つの重要な特徴と言える。
あとは、対面相手がAIかどうか確認できる?パスワード生成してって言ったら。
サードパーティーとか、内部的LLMに使っているやるとかも気を付けて
ここまでのことって、内部的にClaude, ChatGPT, Geminiを使っていれば何にでも当てはまる可能性がある。
他のコーディングエージェントもそうだし、AIブラウザとかも。
パスワードがAI生成される場合には、注意しなければならない。
そして、文字種類の多さと長さが強いパスワードじゃないと、最後に言っておこう。