Windows の認証について調べていると、「ハッシュ」「暗号化」「署名」「鍵」といった言葉が、説明なしで出てきます。NTLM は「NT ハッシュから応答を計算する」、Kerberos は「チケットを鍵で暗号化する」、TLS は「証明書の公開鍵を使う」といった具合です。この記事では、暗号の道具を4つに分けて、身近なたとえと図で説明します。そのうえで、NTLM、Kerberos、SMB、TLS のどこでどの道具が使われているかをつなげます。数式は使いません。
- ハッシュ・HMAC・共通鍵暗号・公開鍵暗号の違い
- パスワードが、ハッシュや鍵としてどう扱われているか
- Windows の認証のどこで、どの道具が使われているか
暗号の4つの道具
「暗号」と聞くと、データを読めなくすること(暗号化)を思い浮かべる人が多いと思います。でも、認証で使う暗号の道具は、それだけではありません。「書き換えられていないか確かめる」「本人が作ったことを示す」といった役割の道具もあります。この記事では、次の4つに分けて考えます。
| 道具 | できること | たとえ |
|---|---|---|
| ハッシュ | データから決まった長さの値を作る。元には戻せない | 指紋 |
| HMAC | 鍵を混ぜてハッシュを作る。書き換えを見つけられる | 2人だけが知る合言葉で作る確認番号 |
| 共通鍵暗号 | 同じ鍵でデータをかけて、同じ鍵で開ける | 合鍵を分け合った南京錠 |
| 公開鍵暗号 | 2本の鍵を使い分けて、隠したり署名したりする | 郵便ポスト、印鑑と印鑑証明 |
このあと、1つずつ見ていきます。最後に、これらを組み合わせた「チャレンジレスポンス」と、Windows の認証との対応をまとめます。
ハッシュ:元に戻せない「指紋」
ハッシュ(ハッシュ関数)は、どんな長さのデータからでも、決まった長さの値を作る計算です。できた値を「ハッシュ値」と呼びます。指紋を見ても、その人の顔や名前は分かりません。でも、2つの指紋を比べれば、同じ人かどうかは分かります。ハッシュ値も、これに似ています。
図の「abc」の値は、SHA-256 の計算例としてよく使われるものです。1文字だけ変えた「abd」では、似ても似つかない値になります。値が少し似ていれば元のデータを推測する手がかりになりますが、ハッシュではそれができないようになっています。
ハッシュ関数にはいくつか種類があり、Windows の認証では古いものも使われています。
| 名前 | 長さ | Windows で使われている場所 | いまの評価 |
|---|---|---|---|
| MD4 | 128ビット | NT ハッシュ(パスワードの保存) | 古い。安全とはいえない |
| MD5 | 128ビット | NTLMv2 の応答(HMAC-MD5) | 攻撃が知られている |
| SHA-1 | 160ビット | Kerberos の AES の鍵づくりとチェックサム(HMAC-SHA1) | 単体では使わない。HMAC では今も使われる |
| SHA-256 | 256ビット | Get-FileHash の既定、証明書の署名、SMB 2.x の署名(HMAC-SHA256) | いま標準的に使われている |
ファイルが本物か確かめる
ハッシュのいちばん身近な使い方は、ダウンロードしたファイルの確認です。配布元がファイルのハッシュ値を公開していれば、手元で計算した値と比べることで、ファイルが途中で壊れたり、すり替えられたりしていないかを確かめられます。
Windows では、PowerShell の Get-FileHash でファイルのハッシュ値を計算できます。アルゴリズムを指定しなければ SHA-256 で計算します。
パスワードをハッシュで保存する
サーバがパスワードをそのまま保存していると、保存場所を盗まれた時点で、全員のパスワードが知られてしまいます。そこで、パスワードそのものではなくハッシュ値を保存しておき、サインインのときは、入力されたパスワードのハッシュ値を計算して比べます。Windows のローカルアカウントでは、パスワードを MD4 で計算した「NT ハッシュ」を、SAM(ローカルのアカウントの保存場所)に保存しています。
ただし、ハッシュで保存すれば安全、というわけではありません。弱点が2つあります。
- 推測される:よく使われるパスワードのハッシュ値を前もって計算しておけば、盗んだハッシュ値と見比べてパスワードを探せる
- ハッシュがパスワードの代わりになる:NTLM の応答は NT ハッシュから計算するので、NT ハッシュを盗んだ人は、パスワードを知らなくても応答を作れる(Pass-the-Hash と呼ばれる攻撃)
ソルト:同じパスワードでも別の値にする
1つ目の弱点への対策が「ソルト」です。ソルトは、ハッシュを計算する前にパスワードに混ぜる値で、ユーザーごとに違う値を使います。ソルトがあれば、同じパスワードでもユーザーごとにハッシュ値が変わるので、前もって計算した一覧が使えなくなります。
NT ハッシュには、ソルトがありません。そのため、同じパスワードのユーザーは同じ NT ハッシュになります。いっぽう Kerberos の AES の鍵は、ドメイン名とユーザー名をソルトにして作ります。さらに計算を 4096 回くり返して、総当たりで当てるのに時間がかかるようにしています(くわしくは共通鍵暗号の節で説明します)。
HMAC:鍵を混ぜて、書き換えを見つける
ハッシュは「同じかどうか」を確かめるのに便利ですが、ネットワークの通信を守るには足りません。攻撃者が途中でデータを書き換え、ハッシュ値も計算し直して付け替えれば、受け取った側は気づけないからです。
そこで、送る側と受け取る側だけが知っている鍵を、ハッシュの計算に混ぜます。これが HMAC(Hash-based Message Authentication Code)です。鍵を知らない人には正しい値を作れないので、書き換えに気づけます。
HMAC が一致すれば、「鍵を知っている相手が作った」「途中で書き換えられていない」の2つが分かります。ただし、HMAC はデータを隠しません。データは読める形のまま送られます。
| 使われている場所 | しくみ |
|---|---|
| SMB 署名 | SMB 2.x は HMAC-SHA256。SMB 3.0 以降は AES-CMAC や AES-GMAC(AES を使って同じ目的を果たすしくみ)。鍵は、認証のときに決まった鍵から作る |
| NTLMv2 の応答 | NT ハッシュから作った鍵で、チャレンジなどの HMAC-MD5 を計算する |
| Kerberos | AES を使うときは、チケットやメッセージのチェックサムに HMAC-SHA1 を 96 ビットに切り詰めた値を使う |
SMB 署名と SMB 暗号化の違いは「SMB署名とSMB暗号化の違いとは?」の記事で説明しています。
共通鍵暗号:同じ鍵でかけて、同じ鍵で開ける
共通鍵暗号は、データを読めない形に変える(暗号化する)鍵と、元に戻す(復号する)鍵が同じ暗号です。合鍵を2本作って分け合った南京錠のようなものです。いま広く使われているのは AES で、鍵の長さが 128 ビットのものと 256 ビットのものがあります。計算が速いので、大きなデータを隠すのに向いています。
図の下にある「鍵をどうやって相手に渡すか」が、共通鍵暗号のいちばんの悩みです。Kerberos と TLS は、これを別々のやり方で解決しています。Kerberos のやり方をこの節で、TLS のやり方を公開鍵暗号の節で説明します。
パスワードから鍵を作る(Kerberos)
Kerberos では、ユーザーのパスワードから鍵を作ります。ユーザーはパスワードを知っていて、DC はパスワードから作った鍵を保存しています。そのため、鍵をネットワークで送らなくても、両方が同じ鍵を持てます。
いまの Kerberos で標準の AES の鍵は、PBKDF2 という方法で作ります。パスワードにソルト(ドメイン名とユーザー名)を混ぜ、HMAC-SHA1 を既定で 4096 回くり返します。いっぽう古い方式の RC4 の鍵は、NT ハッシュそのものです。つまり NT ハッシュを盗まれると、NTLM だけでなく、RC4 を使う Kerberos でもその値が使われてしまいます。
Kerberos では、この鍵で DC が「その場かぎりの鍵(セッションキー)」を包んでユーザーに渡し、以降の通信はセッションキーで守ります。チケットの流れは「Kerberos認証とは?」の記事で説明しています。
Kerberos の暗号の種類
Kerberos で使う暗号の種類は「暗号化タイプ(etype)」と呼ばれ、番号が付いています。アカウントごとにどの種類を使えるかは、AD の msDS-SupportedEncryptionTypes 属性で決まります。
| 暗号化タイプ | 番号 | 属性のビット | 鍵 |
|---|---|---|---|
| AES256-CTS-HMAC-SHA1-96 | 18 | 0x10 | PBKDF2 で作る 256 ビットの鍵 |
| AES128-CTS-HMAC-SHA1-96 | 17 | 0x8 | PBKDF2 で作る 128 ビットの鍵 |
| RC4-HMAC | 23 | 0x4 | NT ハッシュ |
属性の値は、使える種類のビットを足したものです。たとえば AES128 と AES256 の両方なら 0x18(10進で 24)になります。
RC4 の鍵は NT ハッシュそのもので、ソルトもくり返しもないため、チケットを盗んでパスワードを総当たりで当てる攻撃(Kerberoasting)に弱いという問題があります。2022年11月以降の更新プログラムで、暗号化タイプが設定されていないアカウントの既定は AES に変わりました。さらに Microsoft は、DC が RC4 を前提にしない既定の動きへ、2026年の更新プログラム(CVE-2026-20833 への対応)で段階的に切り替えています。RC4 しか使えない古い機器やサービスアカウントがあると、認証に失敗することがあります。
公開鍵暗号:鍵を2本に分ける
公開鍵暗号は、ペアになった2本の鍵を使います。片方の鍵でかけたものは、もう片方の鍵でしか開けられません。1本は「公開鍵」として、だれに渡してもかまいません。もう1本は「秘密鍵」として、持ち主だけが持ちます。代表的なものに、RSA と楕円曲線暗号(ECC)があります。
公開鍵暗号には、使い方が2つあります。「公開鍵で隠す」と「秘密鍵で署名する」です。
公開鍵で隠す
公開鍵は知られてもかまわないので、共通鍵暗号のような「鍵をどうやって渡すか」の悩みがありません。そのかわり、計算に時間がかかるので、大きなデータをそのまま隠すのには向いていません。
秘密鍵で署名する
鍵の役割を逆にすると、「署名」になります。秘密鍵で作った署名は、ペアの公開鍵で確かめられます。秘密鍵を持っているのは本人だけなので、署名が確かめられれば、本人が作ったものだと分かります。
実際には、データ全体ではなく、データのハッシュ値に署名します。データが少しでも書き換えられるとハッシュ値が変わるので、署名と合わなくなります。ここでも、ハッシュが土台として使われています。
証明書:この公開鍵はだれのもの?
公開鍵暗号には、もう1つ問題があります。届いた公開鍵が、本当にその相手のものかどうかです。攻撃者が「FS01 の公開鍵です」と言って自分の公開鍵を渡してくれば、その鍵で隠したデータは攻撃者に読まれてしまいます。
そこで、信頼できる第三者(認証局、CA)が「この公開鍵は fs01.corp.example.com のもの」と署名して保証します。これが証明書です。
Windows には、信頼する CA の一覧(信頼されたルート証明機関)があり、証明書の署名をその CA の公開鍵で確かめます。社内では、AD 証明書サービス(AD CS)を CA にして、スマートカードや LDAPS、Windows Hello for Business の証明書を発行することがあります。
2つの暗号を組み合わせる(TLS)
公開鍵暗号は鍵の受け渡しに強く、共通鍵暗号は速い。そこで、HTTPS などで使われる TLS は、2つを組み合わせています。
最初のハンドシェイクでは、まず、おたがいが出し合った値から同じ共通鍵を計算します(鍵交換)。TLS 1.3 では、鍵そのものはネットワークに流れません。続いてサーバは証明書と署名を送り、ブラウザは証明書を確かめて「本当にそのサーバか」を判断します。そのあとのデータ本体は、決まった共通鍵(AES など)で暗号化して送ります。
チャレンジレスポンス:パスワードを送らずに示す
認証でいちばん大事なのは、「パスワードを知っていること」を、パスワードを送らずに示すことです。ネットワークにパスワードを流せば、盗み見られた時点でおしまいだからです。そこで使われるのが、チャレンジレスポンスです。サーバが毎回ちがうランダムな値(チャレンジ)を送り、クライアントは秘密を使ってその値から応答を計算して返します。
秘密を知らなければ、正しい応答は作れません。また、チャレンジが毎回変わるので、前の応答を盗み見て使い回しても通りません。NTLMv2 では、NT ハッシュとユーザー名・ドメイン名から鍵を作り、その鍵で、サーバのチャレンジ、クライアント側のチャレンジ、時刻などをまとめて HMAC-MD5 で計算します。FS01 は user01 の NT ハッシュを知らないので、チャレンジと応答を DC01 に渡して確かめてもらいます(パススルー認証)。NTLM の流れは「NTLM認証とは?」、パススルー認証は「Netlogonとセキュアチャネルとは?」の記事で説明しています。
Kerberos でも、考え方は同じです。サインインのとき、PC は現在の時刻をユーザーの鍵で暗号化して DC に送ります(事前認証)。DC が自分の持つ鍵で開けて正しい時刻が出てくれば、パスワードを知っていると分かります。チャレンジの代わりに時刻を使っているので、Kerberos では PC と DC の時計が合っている必要があります。
パスワード型と鍵ペア型
NTLM のようなパスワード型のチャレンジレスポンスでは、PC と DC が同じ秘密(NT ハッシュ)を持っています。これに対して、Windows Hello for Business(WHfB)や FIDO2 のセキュリティキーは、公開鍵暗号を使う鍵ペア型です。
WHfB では、設定したときに端末で鍵のペアを作ります。秘密鍵は TPM(端末に組み込まれたセキュリティチップ)で守られ、外に取り出せません。公開鍵だけを Entra ID や AD に登録します。サインインのときは、Entra ID などから届いたランダムな値(ナンス)に秘密鍵で署名し、相手は登録された公開鍵で確かめます。PIN や生体認証は、端末の中で秘密鍵を使えるようにするためのもので、ネットワークには流れません。
鍵ペア型では、サーバ側にあるのは公開鍵だけです。サーバのデータベースを盗まれても、そこから利用者になりすますことはできません。パスワードを使わない認証が勧められているのは、このためです。
Windows の認証のどこで使われているか
ここまでの道具が、Windows のどの機能で使われているかをまとめます。
| 機能 | 使っているもの |
|---|---|
| NTLM | NT ハッシュ(MD4)から作った鍵で、HMAC-MD5 の応答を計算する |
| Kerberos | パスワードから作った共通鍵(AES)で事前認証とチケットを暗号化する。チェックサムは HMAC-SHA1 |
| Kerberos (PKINIT) | パスワードの代わりに、証明書の秘密鍵で署名して TGT をもらう。スマートカードや、WHfB の一部の方式で使う |
| SMB 署名 | HMAC-SHA256、AES-CMAC、AES-GMAC で書き換えを見つける |
| SMB 暗号化 | AES-CCM、AES-GCM でデータを隠す |
| TLS | 証明書(公開鍵)で相手を確かめ、共通鍵で通信を暗号化する |
| WHfB・FIDO2 | 端末の秘密鍵でナンスに署名する |
Kerberos では、場面ごとに違う鍵を使い分けています。どのチケットがどの鍵で守られているかを図にすると、次のようになります。
TGT は krbtgt というアカウントの鍵で暗号化されているので、DC にしか開けられません。サービスチケットは FS01 のコンピュータアカウント(FS01$)の鍵で暗号化されているので、FS01 だけが開けられます。どれも共通鍵暗号で、鍵は各アカウントのパスワードから作っています。
確認に使うコマンド
PC(PowerShell):ファイルの SHA-256 のハッシュ値を計算する
Get-FileHash -Path .\tool.zip
PC(コマンドプロンプト):ファイルの SHA-256 のハッシュ値を計算する
certutil -hashfile tool.zip SHA256
PC(コマンドプロンプト):持っている Kerberos のチケットと、その暗号化タイプを表示する
klist
管理用PC(PowerShell):ユーザーが使える Kerberos の暗号化タイプを表示する
Get-ADUser -Identity user01 -Properties msDS-SupportedEncryptionTypes | Select-Object Name, msDS-SupportedEncryptionTypes
PC(PowerShell):信頼されたルート証明機関の一覧を表示する
Get-ChildItem -Path Cert:\LocalMachine\Root | Select-Object Subject, NotAfter
klist では、チケットごとの「KerbTicket Encryption Type」の行で、チケットがどの暗号化タイプで暗号化されているかが分かります。msDS-SupportedEncryptionTypes は10進で表示されるので、先ほどの表のビットに直して読みます。値が空なら、DC の既定の設定が使われます。
まとめ
| 道具 | ひとことで |
|---|---|
| ハッシュ | 元に戻せない指紋。パスワードの保存とファイルの確認に使う。NT ハッシュはソルトなしの MD4 |
| HMAC | 鍵を混ぜたハッシュ。書き換えを見つけるが、中身は隠さない |
| 共通鍵暗号 | 同じ鍵でかけて開ける。速い。鍵の渡し方が課題で、Kerberos はパスワードから鍵を作る |
| 公開鍵暗号 | 公開鍵で隠し、秘密鍵で署名する。証明書で「だれの鍵か」を保証する |
| チャレンジレスポンス | 毎回ちがう値に秘密で応答し、パスワードを送らずに示す。鍵ペア型ならサーバに秘密を置かずに済む |
認証のしくみの説明で「NT ハッシュから計算する」「鍵で暗号化する」「秘密鍵で署名する」と出てきたら、4つの道具のどれを使っているのかを思い出してみてください。何を守っていて、何が盗まれると困るのかが見えてきます。
- Passwords technical overview(Microsoft Learn)
- [MS-NLMP] 3.3.2 NTLM v2 Authentication(Microsoft Learn)
- RFC 3962:Advanced Encryption Standard (AES) Encryption for Kerberos 5
- RFC 4757:The RC4-HMAC Kerberos Encryption Types Used by Microsoft Windows
- RFC 2104:HMAC: Keyed-Hashing for Message Authentication
- RFC 6150:MD4 to Historic Status
- RFC 6194:Security Considerations for the SHA-0 and SHA-1 Message-Digest Algorithms
- RFC 4556:Public Key Cryptography for Initial Authentication in Kerberos (PKINIT)
- RFC 8446:The Transport Layer Security (TLS) Protocol Version 1.3
- Detect and remediate RC4 usage in Kerberos(Microsoft Learn)
- How to manage Kerberos KDC usage of RC4 for service account ticket issuance changes related to CVE-2026-20833(Microsoft サポート)
- Overview of Server Message Block signing in Windows(Microsoft Learn)
- SMB security enhancements(Microsoft Learn)
- How Windows Hello for Business works(Microsoft Learn)
- Get-FileHash(Microsoft Learn)
コメント