ハッシュ値の文字列表現からハッシュ方式を判定する方法 - 長さ・文字種・接頭辞で候補を絞る実務手順
ログや DB に残っている 5f4dcc3b5aa765d61d8327deb882cf99 や $2b$12$... のような文字列を見て、「これは何のハッシュか」を判定したい場面はかなりあります。既存システムの移行、認証方式の調査、ログ解析、他社システム連携では、ここで止まることが珍しくありません。
ただ、ここで危ないのは 長さだけで即断すること です。
64 桁の 16 進文字列を見て「SHA-256 ですね」と言い切るのは早すぎます。SHA3-256、SHA-512/256、BLAKE2s-256、BLAKE3 の既定 32-byte 出力でも同じ長さになりえます。逆に、$2b$ や $argon2id$ のように 接頭辞やパラメータまで含む保存形式 は、文字列だけでかなり高い精度で判定できます。
この記事では、hash という言葉を広めに使い、MD5 / SHA-2 / SHA-3 のようなメッセージダイジェストだけでなく、bcrypt / scrypt / Argon2 / PBKDF2 のような パスワード保存用の文字列表現 も含めて扱います。
内容は 2026 年 4 月時点で公開されている RFC、NIST、Linux crypt(5)、Apache、Django、Spring Security などの公式資料をもとに整理しています。
目次
- まず結論
- 一目で見る判定表
- 実務での判定手順
- よくある誤判定
- 100% 確定したいときの確認順
- まとめ
- このテーマがつながるサービス
- 参考資料
1. まず結論
先に短くまとめると、結論は次です。
-
接頭辞や区切りがある保存形式 は、文字列だけでかなり特定しやすいです。
例:$argon2id$...,$2b$...,$5$...,$6$...,{SHA}...,pbkdf2_sha256$... -
プレーンな 16 進文字列や Base64 だけ では、たいてい「候補を絞る」までです。
例:32 hex = MD5 かもしれないが、MD4 / NTLM 由来かもしれない -
文字種は長さと同じくらい重要 です。
+/=があれば RFC 4648 の Base64 らしい、.が入っていて$区切りならcrypt(3)系らしい、といった見分けが効きます。 -
100% 確定したいなら文脈が必要 です。
/etc/shadowなのか、.htpasswdなのか、Django のauth_userなのか、Spring Security なのかで話が変わります。
要するに、「文字列だけで特定できる方式」と「文字列だけでは候補群までしか分からない方式」は別物 です。
ここを分けて考えると、調査がかなり速くなります。
2. 一目で見る判定表
2.1 接頭辞や形式マーカーでほぼ特定できるもの
判定の強さは次の意味です。
- 強: 文字列だけでほぼ特定できる
- 中: 候補はかなり絞れるが、実装差異に注意がいる
- 弱: 長さや見た目だけでは断定できない
| 見た目の特徴 | まず疑う方式 | 判定の強さ | 補足 | 例 |
|---|---|---|---|---|
$argon2id$... |
Argon2id | 強 | PHC string format。v=, m=, t=, p= が続くことが多い |
$argon2id$v=19$m=65536,t=3,p=4$MDEyMzQ1Njc4OWFiY2RlZg$uKZLaN6muIyoyIYr5waqw3y+zaDbe9aLSPj6Ln/rbz4 |
$argon2i$... |
Argon2i | 強 | 同上 | $argon2i$v=19$m=65536,t=3,p=4$MDEyMzQ1Njc4OWFiY2RlZg$Kx1koF/7n8EytGJYTS5krh+ag+FlG5ksM4xOsjOSDvo |
$argon2d$... |
Argon2d | 強 | 同上 | $argon2d$v=19$m=65536,t=3,p=4$MDEyMzQ1Njc4OWFiY2RlZg$HLIGA+T1bwK8akx3LGOco+Df+PvxX6cIXhycO7O7t6c |
$2a$... / $2b$... / $2y$... |
bcrypt | 強 | 2 桁コスト + crypt 系 alphabet | $2b$12$9YQ2u/e5Y/ArOnG.gJKxK.0makLATcYLP1q.Nsabzrw7XErYCfoYO |
$1$... |
md5crypt | 強 | Unix 系の MD5 パスワード保存形式 | $1$vA7mQ9xZ$Erz32JUFnZ9991KdU5.N3. |
$5$... |
sha256crypt | 強 | plain SHA-256 ではない | $5$rounds=5000$N3v8Kx2Lq9Rt$uOTla5GAHaRH2aHlUSjkrZUBCuFiahQZ36O/seB39r3 |
$6$... |
sha512crypt | 強 | plain SHA-512 ではない | $6$rounds=5000$N3v8Kx2Lq9Rt$6LUcSUAELX3aC/.60pTB.TFLTQi1mOGRCwKqNCqtRSaXjorxj01HJ9oNni97Kci1uDt7a/Kn4t3OS20Dw/.vi1 |
$7$... |
scrypt (crypt 系) | 強 | Linux crypt(5) 系実装で見かける |
$7$CU..../....k2XAnEHBqQ1Ct2aMXFKNa/$y3Q0e/UlCHacIGWQshgvvz6UIbP.BCja.5BfVWP2Ml8 |
$y$... |
yescrypt | 強 | 新しめの Linux 系で見かける | $y$j9T$k2XAnEHBqQ1Ct2aMXFKNa/$OVYXzjlkiQpWT/F1CUE0JrvV4phLY8FB.ofDttnrSQ7 |
$apr1$... |
Apache APR1-MD5 | 強 | .htpasswd でよく見る |
$apr1$vA7mQ9xZ$ZE64.ohiyK11sPZmtnJZQ. |
{SHA}... |
SHA-1 digest の Base64 表現 | 強 | Apache / LDAP 系でよく見る | {SHA}VBPuJHI7uixaa6LQGWx4s+5GKNE= |
{SSHA}... |
salted SHA-1 | 強 | LDAP 系 | {SSHA}/OczD0GNNkOAUPbYhA3L9fjmcyBCbHVlTWVzYTQyIQ== |
{MD5}... / {SMD5}... |
MD5 / salted MD5 | 強 | LDAP 系 | {MD5}X03MO1qnZdYdgyfeuILPmQ=={SMD5}fOn1rOv4ZH0OrO/KT9H0fEJsdWVNZXNhNDIh |
pbkdf2_sha256$... |
PBKDF2-HMAC-SHA256 | 中〜強 | Django など、実装が形式名を前置している | pbkdf2_sha256$600000$N3v8Kx2Lq9Rt$CLxGB+zTiV1IdOt2y4m9JpaAONzHuRTOd96xKQwRQAs |
{bcrypt}$2b$... |
bcrypt | 強 | Spring Security の {id} ラッパー付き |
{bcrypt}$2b$12$9YQ2u/e5Y/ArOnG.gJKxK.0makLATcYLP1q.Nsabzrw7XErYCfoYO |
{pbkdf2}... / {scrypt}... |
実装ラベル付き方式 | 中〜強 | Spring Security など、アルゴリズム本体よりラッパー形式を見分ける | {pbkdf2}sha256$600000$Qmx1ZU1lc2E0MiE$4eNuai1qNkgs1kXz3+tBUMzAexVsSUz9SrQKEhbk0Cw{scrypt}ln=14,r=8,p=1$Qmx1ZU1lc2E0MiE$xAgBRhXbMtHB1UHUR0br5bI+1XdXWKbwauiFv5VRQBY |
この表のポイントは、先頭の数文字に意味がある形式は強い ということです。
とくに $...$ で区切られたものは、Unix crypt(3) / MCF / PHC 系の可能性が高く、長さより先に prefix を見たほうが早い です。
2.2 プレーンな 16 進 / Base64 の長さで候補を絞る表
こちらは prefix なしの「ただの digest 文字列」 を見るときの表です。
: や -、空白が混ざる表現は、まず区切りを取り除いて長さを数えます。
| 生バイト長 | 16 進文字数 | Base64 文字数 (= あり / なし) |
主な候補 | 例 |
|---|---|---|---|---|
| 4 | 8 | 8 / 6 | CRC32 などのチェックサム | cbf43926 |
| 16 | 32 | 24 / 22 | MD5、MD4、NTLM 系 | 5f4dcc3b5aa765d61d8327deb882cf99 |
| 20 | 40 | 28 / 27 | SHA-1、RIPEMD-160 | da39a3ee5e6b4b0d3255bfef95601890afd80709 |
| 28 | 56 | 40 / 38 | SHA-224、SHA-512/224、SHA3-224 | d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f |
| 32 | 64 | 44 / 43 | SHA-256、SHA-512/256、SHA3-256、BLAKE2s-256、BLAKE3 の既定 32-byte 出力 | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 |
| 48 | 96 | 64 / 64 | SHA-384、SHA3-384、BLAKE2b-384 | 38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b |
| 64 | 128 | 88 / 86 | SHA-512、SHA3-512、BLAKE2b-512、Whirlpool | cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e |
ここで大事なのは、長さが一致しても方式は一意に決まらない ことです。
とくに 32 / 64 / 128 桁の 16 進は候補が多く、これだけで断定すると外しやすいです。
2.3 迷いやすい代表例
| 文字列の見え方 | ありがちな即断 | 実際の見方 | 例 |
|---|---|---|---|
5f4dcc3b5aa765d61d8327deb882cf99 |
MD5 で確定 | MD5 っぽいが、MD4 / NTLM 系やアプリ固有の MD5 利用もありうる | 8846f7eaee8fb117ad06bdd830b7586c |
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 のような 64 hex |
SHA-256 で確定 | SHA-256 候補ではあるが、SHA3-256 / SHA-512/256 / BLAKE2s-256 / BLAKE3 もありうる | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 |
$6$rounds=5000$salt$hash |
SHA-512 の hex 表現 | そうではなく sha512crypt という password hash 文字列 | $6$rounds=5000$N3v8Kx2Lq9Rt$6LUcSUAELX3aC/.60pTB.TFLTQi1mOGRCwKqNCqtRSaXjorxj01HJ9oNni97Kci1uDt7a/Kn4t3OS20Dw/.vi1 |
{SHA}VBPuJHI7uixaa6LQGWx4s+5GKNE= |
何かの「SHA」 | Apache / LDAP 系では Base64 化した SHA-1 digest を指すことが多い | {SHA}VBPuJHI7uixaa6LQGWx4s+5GKNE= |
{bcrypt}$2b$12$... |
{bcrypt} という独自方式 |
Spring Security のラッパー付き bcrypt | {bcrypt}$2b$12$9YQ2u/e5Y/ArOnG.gJKxK.0makLATcYLP1q.Nsabzrw7XErYCfoYO |
3. 実務での判定手順
ここからは、実際にどう見るかを順番に整理します。
おすすめは prefix → 区切り → 文字種 → 長さ → 文脈 の順です。
3.1 まず先頭の記号を見る
最初の 1 文字から 10 文字くらいで、かなり絞れます。
-
$argon2id$/$argon2i$/$argon2d$
Argon2 の PHC string format を強く疑います。構成要素は 2.1 の例列を見ると追いやすいです。 -
$2a$/$2b$/$2y$
bcrypt を強く疑います。 -
$1$/$5$/$6$/$7$/$y$
Unixcrypt(3)系の password hash を疑います。 -
{SHA}/{SSHA}/{MD5}/{SMD5}
LDAP / Apache 系の表現を疑います。 -
{bcrypt}/{pbkdf2}/{scrypt}
Spring Security のような 実装ラベル付き保存形式 を疑います。
ここでのコツは、「アルゴリズム本体」だけでなく「保存形式」も見る ことです。
たとえば $6$ は「SHA-512 の digest」ではなく、「SHA-512 を使った password hash 文字列」です。ここを取り違えると、その後の調査がずれます。
3.2 区切り文字の数を見る
次に、$, :, {}, ,, = のような区切りを見ます。
-
$が複数ある
パラメータ、salt、hash を一緒に持つ形式を疑います。Argon2、bcrypt、sha256crypt、sha512crypt などが典型です。 -
{name}で始まる
LDAP / Spring Security など、方式名を明示したラッパー を疑います。 -
algo:salt:hashやalgo$iterations$salt$hashのような形
フレームワークやアプリ固有形式を疑います。Django のpbkdf2_sha256$iterations$salt$hashはその典型です。
区切りが多い文字列ほど、方式を特定しやすい です。
逆に、ただの 16 進や Base64 が 1 塊で置かれているだけだと、かなり曖昧になります。
3.3 文字種を見る
文字種は、長さと同じくらい重要です。
16 進表現
[0-9a-fA-F] だけでできているなら、まずは 16 進表現を疑います。
この場合は 文字数 ÷ 2 = 生バイト長 です。
- 32 hex → 16 bytes
- 40 hex → 20 bytes
- 64 hex → 32 bytes
- 128 hex → 64 bytes
RFC 4648 の Base64 / Base64url
+ / = があれば、まず普通の Base64 を疑います。
- _ があれば Base64url を疑います。
padding の = が省略されることもあるので、43 / 44, 86 / 88 のような「両方ありうる長さ」を持ちます。
crypt 系の radix64
. と / が出てきて、しかも $...$ 区切りなら、普通の Base64 より crypt 系の alphabet を疑うほうが自然です。
bcrypt、sha256crypt、sha512crypt、md5crypt、yescrypt、scrypt などは、この系統の文字集合を使います。
ここは地味ですが、かなり効きます。
. が入っているから壊れた Base64 だ と見てしまうと、bcrypt や crypt(3) 系を見落としやすくなります。
3.4 長さを数える
文字種を見たら、次に長さです。
考え方は単純です。
- 16 進なら
生バイト長 = 文字数 / 2 - Base64 なら
文字数 ≒ 4 × ceil(生バイト長 / 3)
ただし padding の=が省略されると 0〜2 文字短くなります
この段階で候補を絞ります。
ただし、64 hex を見て SHA-256 で確定、のような飛躍はしない ほうが安全です。
3.5 文脈で確定する
最後に効くのは文脈です。ここで 100% に近づけます。
-
/etc/shadowにある
$y$,$6$,$5$,$1$など Linux の password hash 形式を疑う -
.htpasswdにある
$apr1$,{SHA}, bcrypt など Apache 系を疑う -
Django の設定や
auth_user.passwordにある
pbkdf2_sha256$...やargon2$...のような Django 形式を疑う -
Spring Security の認証テーブルにある
{bcrypt}...や{pbkdf2}...のような{id}付き形式を疑う -
SMB / AD 連携まわりにある 32 hex
NTLM / MD4 系の可能性を強く考える
実務では、文字列そのものだけ見るより、保存元の製品・フレームワーク・設定ファイル名を見るほうが早い 場面がかなりあります。
4. よくある誤判定
4.1 64 hex = SHA-256 と決め打ちする
これはかなりありがちです。
もちろん SHA-256 は有力候補ですが、同じ 32-byte 出力を持つ方式は複数あります。SHA3-256、SHA-512/256、BLAKE2s-256、BLAKE3 の既定出力なども同じ長さです。
長さは候補群を作る材料であって、確定材料ではありません。
4.2 $6$ を plain SHA-512 と誤解する
$6$... は sha512crypt の prefix です。
これは「SHA-512 の hex digest」ではなく、salt や rounds を含む password hash 文字列 です。
同様に、
$5$は sha256crypt$1$は md5crypt
です。
prefix が付いている時点で、もう「ただの digest」ではありません。
4.3 {SHA} を「SHA-256 か SHA-512 のどれか」と思う
Apache や LDAP の文脈で {SHA} は、ふわっと「SHA 系」の意味ではありません。
多くの場合、Base64 化した SHA-1 digest を指します。{SSHA} は salted SHA-1 です。
{SHA} の見た目だけで「何かの SHA」と曖昧に扱うと、検証コードや移行処理を間違えます。
4.4 パスワードハッシュとコンテンツハッシュを同じものとして扱う
同じ「ハッシュ文字列」でも、目的が違います。
- ファイル整合性確認の digest
- API の署名用 digest
- パスワード保存用 hash / KDF 文字列
この 3 つは見た目が似ていても、扱いが違います。
とくに password hash は salt、rounds、memory cost、parallelism などを文字列に含むことが多く、「生 digest を比べる」発想では見抜けません。
4.5 XOF や可変長 digest を忘れる
SHAKE128 / SHAKE256 は XOF なので、出力長を自由に選べます。
BLAKE2 も digest length を変えられますし、BLAKE3 も extendable output を持ちます。
つまり、「この長さだからこの方式」 という推定は、固定長の古典的 digest を前提にしすぎると外します。
5. 100% 確定したいときの確認順
移行や認証連携では、最終的に 確定 が必要です。そのときは次の順で見ると事故りにくいです。
5.1 保存元を特定する
まず、どこから来た文字列かを確定します。
- Linux の shadow か
- Apache / Nginx の basic auth か
- LDAP か
- Django / Spring Security か
- 独自アプリの DB か
文字列単体より、保存元の仕様 のほうが強いことが多いです。
5.2 公式ドキュメントで「保存形式」を調べる
次に、アルゴリズム名ではなく 保存形式 を調べます。
Django password formatSpring Security password storage formatcrypt(5) sha512crypt formatApache htpasswd password formats
のように、format / storage / encoding をキーワードにすると見つけやすいです。
5.3 既知の平文があるなら、候補方式で実際に照合する
テスト用アカウントや既知の平文があるなら、候補方式で実際に計算して比較するのが早いです。
このとき、password hash では salt や rounds を文字列から取り出して再計算 する必要があります。
5.4 実装コードか設定を確認する
調査対象が自社システムなら、最終的にはコードや設定を見るのがいちばん確実です。
- 使用ライブラリ
- フレームワークの設定
- 生成時オプション
- 出力エンコード方式(hex / Base64 / Base64url / crypt alphabet)
ここを見れば、たいてい決着がつきます。
5.5 今後のために、方式ラベル付きで保存する
これから設計する側なら、方式を文字列に埋め込む形式 を選ぶと、将来の移行がかなり楽になります。
- Argon2 の PHC string format
- Spring Security の
{id}encodedPassword - Django の
algo$iterations$salt$hash - Unix
crypt(3)系の prefix 付き形式
こうしておくと、後から見た人が迷いにくいです。
逆に「ただの 64 hex」だけを DB に置く設計は、将来の自分にやさしくありません。
6. まとめ
ハッシュ値の文字列表現から方式を見分けるときは、次の順で見ると整理しやすいです。
- prefix があるか
- 区切り文字が何か
- 文字集合が何か
- 長さが何バイト相当か
- 保存元の文脈が何か
いちばん大事なのは、次の 2 点です。
- 接頭辞付きの保存形式はかなり特定しやすい
- プレーンな 16 進 / Base64 は候補群までしか分からないことが多い
なので、実務での判断はこうなります。
$argon2id$...,$2b$...,$6$...,{SHA}...,pbkdf2_sha256$...なら、文字列だけでかなり前に進める32 / 40 / 64 / 128桁の 16 進だけなら、断定ではなく「候補を絞る」と考える- 本当に確定が必要なら、保存元の製品・設定・実装まで見る
この順で見れば、調査がかなり速くなります。
逆に、長さだけで即断すると、静かに遠回りします。
7. このテーマがつながるサービス
技術相談・設計レビュー
既存 DB に残ったパスワードハッシュの方式特定、認証基盤の移行、Windows / Web 混在システムのログ調査では、文字列の見た目だけでなく、保存元の実装や移行方針まで整理する必要があります。方式特定から移行設計まで、まとめて見ると事故を減らしやすいです。
不具合調査・原因解析
「この文字列が何なのか分からないので検証が進まない」という調査は珍しくありません。ログ、設定ファイル、DB スキーマ、アプリ実装のどこで方式が決まっているのかを切り分けると、原因特定がかなり早くなります。
8. 参考資料
- RFC 1321 - The MD5 Message-Digest Algorithm
- NIST FIPS 180-4 - Secure Hash Standard (SHA-1, SHA-2, SHA-512/224, SHA-512/256)
- NIST FIPS 202 - SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
- PHC string format specification
- Argon2 reference implementation
- RFC 7693 - The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)
- BLAKE3 C README - default output length and extendable output
- crypt(5) - prefixes and hashed passphrase formats
- Apache HTTP Server 2.4 - Password Formats
- slappasswd(8) - RFC 2307 schemes such as {SHA} and {SSHA}
- Django documentation - example of
pbkdf2_sha256$... - Spring Security -
DelegatingPasswordEncoderstorage format{id}encodedPassword
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
自動アップデート機能のセキュリティ基本 - ダメなパターンとベストプラクティス
自動アップデートを便利機能ではなく信頼境界として扱うために、HTTPS だけで守れない理由、signed metadata、クライアント側検証、鍵分離、rollback と fail-closed、Windows で既存基盤を優先する考え方を整理します。
なぜメールセキュリティにおいて PPAP はダメなのか。正しいやり方は?
パスワード付き ZIP をメールで送り、別メールでパスワードを送る PPAP がなぜ危ないのかを整理し、TLS / S/MIME / 認証付きダウンロードという現実的な代替策を実務目線でまとめます。
中小企業向けの一斉メール配信を、特定サービスに縛られず設計する方法
中小企業が既存ドメインやサイトを活かしながら、数十〜数百件規模の案内メールを安全に送るための実務設計を整理します。
Windows での DLL の名前解決の仕組み - 検索順序、Known DLLs、API set、SxS を実務向けに整理
Windows の DLL 名前解決を、DLL search order、Known DLLs、loaded-module list、API set、SxS manifest、LoadLibrary 系 API の影響まで実務向けに整理します。
Windows の管理者特権が必要になるのはいつなのか - UAC、保護領域、設計上の見分け方
Windows で管理者特権が必要になる場面を、UAC、保護領域、サービス、ドライバ、per-user/per-machine 設計の観点から実務向けに整理します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
技術相談・設計レビュー
既存システムのログ、DB、認証方式、保存形式を切り分けてハッシュ方式を特定し、移行や調査の判断を整理する用途に向いているため。