ハッシュ値の文字列表現からハッシュ方式を判定する方法 - 長さ・文字種・接頭辞で候補を絞る実務手順

· · ハッシュ, セキュリティ, パスワード, 既存資産活用, 技術調査

ログや 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 などの公式資料をもとに整理しています。

目次

  1. まず結論
  2. 一目で見る判定表
  3. 実務での判定手順
  4. よくある誤判定
  5. 100% 確定したいときの確認順
  6. まとめ
  7. このテーマがつながるサービス
  8. 参考資料

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$
    Unix crypt(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:hashalgo$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 format
  • Spring Security password storage format
  • crypt(5) sha512crypt format
  • Apache 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. まとめ

ハッシュ値の文字列表現から方式を見分けるときは、次の順で見ると整理しやすいです。

  1. prefix があるか
  2. 区切り文字が何か
  3. 文字集合が何か
  4. 長さが何バイト相当か
  5. 保存元の文脈が何か

いちばん大事なのは、次の 2 点です。

  • 接頭辞付きの保存形式はかなり特定しやすい
  • プレーンな 16 進 / Base64 は候補群までしか分からないことが多い

なので、実務での判断はこうなります。

  • $argon2id$..., $2b$..., $6$..., {SHA}..., pbkdf2_sha256$... なら、文字列だけでかなり前に進める
  • 32 / 40 / 64 / 128 桁の 16 進だけなら、断定ではなく「候補を絞る」と考える
  • 本当に確定が必要なら、保存元の製品・設定・実装まで見る

この順で見れば、調査がかなり速くなります。
逆に、長さだけで即断すると、静かに遠回りします。

7. このテーマがつながるサービス

技術相談・設計レビュー

既存 DB に残ったパスワードハッシュの方式特定、認証基盤の移行、Windows / Web 混在システムのログ調査では、文字列の見た目だけでなく、保存元の実装や移行方針まで整理する必要があります。方式特定から移行設計まで、まとめて見ると事故を減らしやすいです。

不具合調査・原因解析

「この文字列が何なのか分からないので検証が進まない」という調査は珍しくありません。ログ、設定ファイル、DB スキーマ、アプリ実装のどこで方式が決まっているのかを切り分けると、原因特定がかなり早くなります。

8. 参考資料

  1. RFC 1321 - The MD5 Message-Digest Algorithm
  2. NIST FIPS 180-4 - Secure Hash Standard (SHA-1, SHA-2, SHA-512/224, SHA-512/256)
  3. NIST FIPS 202 - SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
  4. PHC string format specification
  5. Argon2 reference implementation
  6. RFC 7693 - The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)
  7. BLAKE3 C README - default output length and extendable output
  8. crypt(5) - prefixes and hashed passphrase formats
  9. Apache HTTP Server 2.4 - Password Formats
  10. slappasswd(8) - RFC 2307 schemes such as {SHA} and {SSHA}
  11. Django documentation - example of pbkdf2_sha256$...
  12. Spring Security - DelegatingPasswordEncoder storage format {id}encodedPassword

関連する記事

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

関連トピック

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

このテーマがつながるサービス

この記事は次のサービスページにつながります。近い入口からご覧ください。

ブログ一覧に戻る