【図解】Windowsの認証は何を確かめている?ユーザー・コンピューター・DCが持つ「同じ鍵」と、確かめるもの・払い出すものを初心者向けに解説

Windows の認証を調べていると、「Kerberos 認証」「NTLM 認証」「コンピューターの認証」「パススルー認証」など、いろいろな名前の認証が出てきます。チケットをもらう、トークンを作る、といった言葉も出てきて、ひとつひとつはなんとなく分かっても、「結局、何を確かめているのか」がすっきりしないことがあります。

実は、これらの認証はどれも同じ考え方の上に成り立っています。前もって同じ秘密(鍵)を持っている2人が、その秘密を相手に見せずに「自分も同じ秘密を持っている」と示し合う、という考え方です。この記事では、だれとだれが同じ鍵を持っているのか、その鍵はどうやって同じに保たれているのか、そして認証のたびに何を確かめて何を払い出しているのかに絞って、図とシーケンスで整理します。

この記事でわかること
  1. 認証の正体:同じ秘密を、見せずに証明するしくみ
  2. ユーザー・コンピューター・サーバ・DC が、それぞれどの鍵を持っているか
  3. パスワードを変えたとき、両方の鍵がどうやってそろうのか
  4. Kerberos・NTLM・セキュアチャネルで、何を確かめて何を払い出しているか

認証の正体:同じ秘密を、見せずに証明する

認証とは、「あなたはだれか」を確かめることです。Windows のドメインでは、その確かめ方の土台に「同じ秘密を持っているかどうか」を使います。ユーザーならパスワード、コンピューターなら自動で決まったパスワードが、その秘密です。

ただし、秘密をそのまま相手に送るわけにはいきません。途中で見られたら終わりですし、毎回同じ値を送るなら、それを記録してまねされてしまいます。そこで、次の2つの方法で「秘密を見せずに、持っていることだけを示す」ようにしています。

NG秘密をそのまま送るA → Bパスワードそのもの途中で見られたら終わり。毎回同じなので、まねもされる方法1NTLM・セキュアチャネル問題を出して答えさせるB → A毎回ちがう問題(乱数)A → B問題と秘密から計算した答えB も同じ計算をして、答えが一致すれば本人方法2Kerberos秘密の鍵で暗号化して送るA → B今の時刻を、秘密の鍵で暗号化したものB が同じ鍵で開けられて、時刻が今に近ければ本人
図1 秘密を見せずに証明する方法

方法1は「チャレンジレスポンス」と呼ばれ、NTLM とセキュアチャネルが使います。方法2は Kerberos が使う方法です。どちらにも共通するのは、次の3点です。

  • 2人は、前もって同じ秘密を持っている
  • 秘密そのものは、ネットワークに流さない
  • 毎回ちがう値(乱数や時刻)を混ぜるので、前の答えを使い回せない

「同じ鍵で正しく計算できた」「同じ鍵で開けられた」ということは、その鍵を持っているということです。そして、その鍵を持っているのは本人と DC だけなので、本人だと判断できます。認証の仕組みは、突き詰めるとこれだけです。暗号やチャレンジレスポンスの基礎は「暗号の基礎」の記事で説明しています。

だれとだれが同じ鍵を持っているか

では、ドメインの中では、だれとだれが同じ鍵を持っているのでしょうか。ポイントは、鍵の組み合わせは必ず「アカウント」と「DC」だということです。

DC01(AD)すべてのアカウントの鍵を持つuser01 の鍵人が決めたパスワードから作るuser01(人)サインインのたびに、入力したパスワードから同じ計算で作る同じ鍵PC01$ の鍵参加時に自動で決まるパスワードからPC01自分の中の保護された場所に保存30日ごとに自分で変える同じ鍵FS01$ の鍵参加時に自動で決まるパスワードからFS01自分の中の保護された場所に保存30日ごとに自分で変える同じ鍵krbtgt の鍵TGT 専用。すべての DC が同じものを持つDC のほかには、だれも持たないDC は全員の鍵を持つ「合鍵の管理人」。PC01 と FS01 は、おたがいの鍵を持たない
図2 だれがどの鍵を持っているか
組み合わせ秘密のもとDC 側の持ち方アカウント側の持ち方
ユーザー と DC人が決めたパスワードパスワードから作った鍵(NT ハッシュや Kerberos の鍵)を、AD のデータベースに暗号化して保存する。パスワードそのものは保存しない保存しない。サインインのたびに、入力したパスワードから同じ計算で鍵を作る
コンピューター と DCドメイン参加のときに自動で決まる、長いランダムなパスワードユーザーと同じく、鍵として AD に保存するコンピューター自身の保護された場所に保存する。既定で30日ごとに自分で変える
サービス と DCサービスを動かすアカウント(コンピューターアカウントやサービスアカウント)のパスワード同じく AD に保存するサービスを動かすサーバが持つ
DC と DCkrbtgt アカウントのパスワードすべての DC が同じ鍵を持つ(AD の複製で配る)DC のほかには、だれも持たない

ここで大事なのは、DC はすべてのアカウントの鍵を持っていること、そしてPC とサーバのあいだには、長く使う共通の鍵がないことです。PC01 は FS01 の鍵を知らず、FS01 も user01 の鍵を知りません。それでも PC01 が FS01 に自分を証明できるのは、両方の鍵を持っている DC が間を取り持つからです。

DC01PC01(user01)FS01user01 の鍵(長く使う)FS01$ の鍵(長く使う)長く使う共通の鍵はない→ DC が「その場限りの鍵」を届けるDC が、両方の鍵を使って間を取り持つ。これが「チケット」や「パススルー認証」
図3 認証の三角形

Kerberos の「チケット」も、NTLM の「パススルー認証」も、この間の取り持ち方の違いです。Kerberos では DC がチケットを作って PC に持たせ、NTLM ではサーバが DC に答え合わせを頼みます。アカウントの種類については「ユーザー・コンピュータ・サービスアカウントの違い」の記事で説明しています。

ローカルアカウントのとき

ドメインではなく、PC やサーバのローカルアカウントでサインインするときは、そのコンピューター自身の SAM(ローカルのアカウントのデータベース)が、DC の役割をします。組み合わせが「アカウント と そのコンピューター」になるだけで、考え方は同じです。

同じ鍵はどうやって「そろう」のか

アカウントと DC が同じ鍵を持つには、どこかで鍵をそろえる必要があります。ここでよく誤解されるのが、「認証のたびに鍵を同期している」というイメージです。実際は、鍵がそろうのはパスワードを決めたとき・変えたときだけです。認証のたびに鍵を送り合うことはありません。

ユーザーのパスワード

ユーザーのパスワードは、管理者がアカウントを作ったときや、利用者が自分で変えたときに DC に届きます。DC はそのパスワードから鍵を作って保存します。PC 側は鍵を保存しておく必要がありません。サインインのたびに、入力されたパスワードから同じ計算で鍵を作れるからです。

① パスワードを変える② 次のサインインuser01PC01DC01DC02PDC エミュレータ古い・新しいパスワード変更の要求暗号化した通り道で送る確かめる古いパスワードを知っているか新しいパスワードから鍵を作り直して保存すぐに知らせるほかの DC にも複製で伝わる新しいパスワードを入力PC01 は入力から同じ計算で鍵を作る新しい鍵で事前認証DC01 の鍵と一致するので成功
図4 ユーザーのパスワードを変えるとき

パスワードの変更を受け付けた DC は、変更をすぐに PDC エミュレータ(ドメインに1台だけある、パスワードの変更を優先的に受け取る役割の DC)に知らせます。ほかの DC には、AD の複製で少し遅れて伝わります。複製が届く前に、まだ古い鍵しか持たない DC でサインインしようとした場合は、その DC が PDC エミュレータに確認を回すので、ふつうは新しいパスワードで入れます。

コンピューターのパスワード

コンピューターのパスワードは人が決めません。ドメイン参加のときに自動で決まり、その後はコンピューター自身が既定で30日ごとに新しいパスワードを作り、DC に書き込みます。

① 30日たつと、PC01 が自分で新しいパスワードを決める② ほかの DC へPC01PC01$DC01DC02長いランダムなパスワードを作る新しいパスワードを書き込むセキュアチャネルで送る成功PC01 は「今」と「1つ前」の2つのパスワードを持っておくAD の複製で伝わる
図5 コンピューターのパスワードを変えるとき

コンピューターは、「今のパスワード」と「1つ前のパスワード」の2つを持っておきます。変更がまだ届いていない相手とやり取りするときは、1つ前のパスワードを使えるようにするためです。変更に成功すると、そのコンピューターのシステムのイベントログに、Netlogon のイベント 5823 が記録されます。

この「変更はコンピューターから始まる」という点が、トラブルの原因にもなります。たとえば、仮想マシンを古いスナップショットに戻すと、コンピューターは古いパスワードに戻りますが、DC はその後に変えた新しいパスワードを持ったままです。2つより多くずれると、1つ前のパスワードでも合わなくなり、「このワークステーションとプライマリ ドメインの信頼関係に失敗しました」になります。直し方は「Netlogonとセキュアチャネル」の記事で説明しています。

krbtgt の鍵

krbtgt は、TGT(チケットを頼むためのチケット)に封をするための特別なアカウントです。この鍵を持つのは DC だけで、すべての DC が同じ鍵を持っています。krbtgt の鍵は、AD の複製で DC どうしに配られます。

認証が起きるタイミング

ここからは、実際の認証の中身を見ていきます。その前に、PC を起動してファイル共有を開くまでに、どの認証がどの鍵で起きているかを並べておきます。

① PC の起動コンピューターの認証使う鍵:PC01$ の鍵PC01 自身が DC に名乗る。PC01$ の TGT と、セキュアチャネル② サインインユーザーの認証(AS 交換)使う鍵:user01 の鍵user01 が DC に名乗る。user01 の TGT③ ファイル共有を開くTGS 交換 → AP 交換使う鍵:TGT と FS01$ の鍵DC に FS01 用のチケットを頼み、FS01 に見せる③’ IP アドレスで開くNTLM使う鍵:user01 の鍵(DC が確認)FS01 の問題に答え、FS01 は DC に答え合わせを頼む
図6 1日の中で起きる認証

見落としやすいのは①です。人がサインインする前に、コンピューターもアカウントとして DC に名乗っています。PC01 は起動すると、PC01$ の鍵で自分の TGT をもらい、DC とのセキュアチャネルを作ります。グループポリシーを読み込むときなどには、このコンピューターの資格情報が使われます。

Kerberos:何を確かめて、何を払い出すか

Kerberos では、DC(KDC)がチケットを作って PC に持たせます。まず、どれがだれの鍵で封をされていて、だれが開けられるのかを押さえておくと、流れが追いやすくなります。

封をしたものだれの鍵で封開けられる人中身TGTkrbtgtDC だけuser01・PAC・ログオンセッション鍵AS 交換の包みuser01user01(PC01)ログオンセッション鍵サービスチケットFS01$FS01 だけuser01・PAC・サービスセッション鍵TGS 交換の包みログオンセッション鍵user01(PC01)サービスセッション鍵オーセンティケータセッション鍵受け取る側user01 の名前と今の時刻チケットは PC01 には開けられない。PC01 は「運ぶだけ」で、開けるのは受け取る側
図7 Kerberos で封をしたものと、開けられる人

封の考え方はシンプルです。受け取る相手が開けられる鍵で封をする。TGT は DC が受け取るので krbtgt の鍵で、サービスチケットは FS01 が受け取るので FS01$ の鍵で封をします。PC01 はどちらのチケットも開けられず、運ぶだけです。PC01 が開けられるのは、自分あての「包み」だけで、その中にセッション鍵(その場限りの鍵)が入っています。

① サインイン(AS 交換)

Kerberos ①:サインイン(AS 交換)PC01user01DC01KDCuser01 + 今の時刻(user01 の鍵で暗号化)事前認証確かめるAD の user01 の鍵で開けられるか・時刻のずれが5分以内か払い出すTGT(krbtgt の鍵で封)+ ログオンセッション鍵(user01 の鍵で封)TGT + 包みPC01 は自分の鍵で包みを開け、ログオンセッション鍵を取り出す。TGT は開けられない
図8 AS 交換で確かめること・払い出すもの

DC は、user01 の鍵で暗号化された時刻を、自分が持つ user01 の鍵で開けます。開けられて、時刻のずれが5分以内なら、user01 のパスワードを知っている本人だと判断します。払い出すのは TGT と、ログオンセッション鍵です。ログオンセッション鍵は user01 の鍵で封をしてあるので、PC01 は入力されたパスワードから作った鍵で開けられます。時刻がずれていると、この時点で失敗します。時刻の話は「Windowsの時刻同期とは?」の記事で説明しています。

コンピューターの起動のときも同じ流れで、user01 の鍵の代わりに PC01$ の鍵を使います。

② サービスチケットをもらう(TGS 交換)

Kerberos ②:サービスチケットをもらう(TGS 交換)PC01user01DC01KDCTGT + オーセンティケータ + cifs/fs01.corp.example.comオーセンティケータ:名前と時刻をログオンセッション鍵で封確かめるkrbtgt の鍵で TGT を開けられるか(=DC が作った本物か)確かめるTGT の中の鍵でオーセンティケータを開け、名前と時刻が合うか確かめるSPN の持ち主(FS01$)がいるか払い出すサービスチケット(FS01$ の鍵で封)+ サービスセッション鍵サービスチケット + 包みここでは user01 の鍵(パスワード)は使わない
図9 TGS 交換で確かめること・払い出すもの

ここでは、user01 の鍵(パスワード)はもう使いません。DC は、krbtgt の鍵で TGT を開けられることで「自分たち DC が作った本物の TGT だ」と分かり、TGT の中に書いておいたログオンセッション鍵でオーセンティケータを開けることで「TGT を持ってきたのは、そのセッション鍵を持つ本人だ」と分かります。そのうえで、SPN の持ち主(ここでは FS01$)の鍵で封をしたサービスチケットを払い出します。SPN については「SPNとは?」の記事で説明しています。

③ サーバに見せる(AP 交換)

Kerberos ③:サーバに見せる(AP 交換)PC01user01FS01ファイルサーバサービスチケット + オーセンティケータSMB のセッション確立などに入れて送る確かめるFS01$ の鍵でチケットを開けられるか・期限内か確かめるチケットの中の鍵でオーセンティケータを開け、名前と時刻が合うか払い出すPAC からアクセストークンを作る(user01 と所属グループ)成功求められれば、時刻をセッション鍵で封をして返す(相互認証)FS01 は DC01 に問い合わせない。自分の鍵で開けられたことが「DC が作った」証拠
図10 AP 交換で確かめること・払い出すもの

FS01 は、自分の鍵でサービスチケットを開けます。FS01$ の鍵を持っているのは FS01 と DC だけなので、開けられたということは、DC が FS01 のために作ったチケットだということです。だから FS01 は、DC に問い合わせなくても、チケットの中身(だれなのか、どのグループに入っているか)を信じられます。

FS01 が最後に払い出すのは、アクセストークンです。チケットの中の PAC(ユーザーと所属グループの SID)をもとに作り、このトークンでファイルのアクセス許可を判断します。アクセストークンについては「アクセストークンとACLとは?」の記事で説明しています。

NTLM:何を確かめて、何を払い出すか

IP アドレスで共有を開いたときなど、Kerberos を使えないときは NTLM になります。NTLM は方法1(問題と答え)を使います。

NTLM:問題と答え(DC が答え合わせ)PC01user01FS01DC01NEGOTIATECHALLENGE(毎回ちがう乱数)AUTHENTICATE(答え)乱数と user01 の鍵から計算FS01 は user01 の鍵を持たない乱数と答えセキュアチャネルで送る確かめるDC01 が同じ計算をして一致するか一致したuser01 の SID・グループ・セッション鍵払い出すFS01 がアクセストークンを作る
図11 NTLM で確かめること・払い出すもの

Kerberos との大きな違いは、サーバが自分では確かめられないことです。答えを確かめるには user01 の鍵が必要ですが、FS01 はそれを持っていません。そこで FS01 は、出した乱数と返ってきた答えを DC に送り、DC が自分の持つ user01 の鍵で同じ計算をして、一致するかを確かめます(パススルー認証)。一致すれば、DC は user01 の SID や所属グループなどの情報を FS01 に返し、FS01 はそれをもとにアクセストークンを作ります。

FS01 から DC への問い合わせは、次に説明するセキュアチャネルを通ります。つまり NTLM の答え合わせは、FS01$ の鍵で守られた通り道の上で行われています。NTLM の詳しい流れは「NTLM認証とは?」の記事で説明しています。

セキュアチャネル:コンピューターと DC の確かめ合い

セキュアチャネルは、コンピューターと DC が、コンピューターアカウントのパスワードを使っておたがいを確かめ、守られた通り道を作るしくみです。Kerberos の AS 交換とちがい、両方が問題を出し合うので、DC が本物かどうかもコンピューター側で確かめられます。

セキュアチャネル:おたがいに問題を出し合うPC01PC01$DC01PC01 の乱数クライアントチャレンジDC01 の乱数サーバチャレンジ両方が「2つの乱数 + PC01$ のパスワード」から同じセッション鍵を作る(鍵は流さない)PC01 の答えセッション鍵から計算確かめるDC01:自分の計算と一致するか(PC01 は本物か)DC01 の答え確かめるPC01:自分の計算と一致するか(DC01 は本物か)払い出すセッション鍵:以降の Netlogon の通信を守る
図12 セキュアチャネルで確かめること・払い出すもの

PC01 と DC01 は、まずおたがいに乱数を送り合います。次に、両方がそれぞれ「2つの乱数」と「PC01$ のパスワード」から、同じセッション鍵を計算します。セッション鍵そのものはネットワークに流れません。そのうえで、PC01 はセッション鍵から計算した答えを送り、DC01 が確かめます。DC01 も答えを返し、PC01 が確かめます。PC01$ のパスワードを知らない相手は正しい答えを作れないので、両方が本物だと分かります。

払い出すのは、このセッション鍵です。以降の Netlogon のやり取り(NTLM のパススルー認証や、コンピューターのパスワードの変更など)は、この鍵で守られます。なお Windows Server 2025 からは、セキュアチャネルを Kerberos で作るしくみも加わっています。

3つの方式を並べると

場面使う鍵確かめること払い出すもの
Kerberos の AS 交換ユーザー(またはコンピューター)の鍵暗号化された時刻を開けられるか。時刻のずれが5分以内かTGT と、ログオンセッション鍵
Kerberos の TGS 交換krbtgt の鍵、ログオンセッション鍵TGT が本物か。オーセンティケータの名前と時刻が合うか。SPN の持ち主がいるかサービスチケットと、サービスセッション鍵
Kerberos の AP 交換サーバの鍵、サービスセッション鍵チケットを開けられるか。期限内か。オーセンティケータの名前と時刻が合うかアクセストークン(PAC から作る)
NTLMユーザーの鍵(DC だけが使う)サーバの乱数への答えが、DC の計算と一致するかユーザーの情報(DC → サーバ)。サーバがアクセストークンを作る
セキュアチャネルコンピューターのパスワードおたがいの答えが、自分の計算と一致するか(両方向)セッション鍵(Netlogon の通信を守る)

表を縦に見ると、払い出すものには2種類あることが分かります。1つは次の相手に見せるためのもの(TGT、サービスチケット)、もう1つはその場限りの鍵(セッション鍵)です。そして最後に、サーバの中でアクセストークンができ、ここで初めて「何をしてよいか」の判断(認可)に移ります。認証と認可の違いは「認証と認可の違いとは?」の記事で説明しています。

鍵がずれると何が起きるか

認証は「両方が同じ鍵を持っている」ことが前提なので、鍵がずれると失敗します。よくあるずれ方を並べておきます。

ずれ方起きること直し方
コンピューターを古いスナップショットやバックアップに戻したDC とセキュアチャネルを作れない。「信頼関係に失敗しました」コンピューターのパスワードをリセットし直す(Test-ComputerSecureChannel -Repair など)
サービスアカウントのパスワードを AD だけで変え、サーバ側の設定を変え忘れたサービスの起動時にログオンできない。チケットを開けず、KRB_AP_ERR_MODIFIED になることもあるサーバ側の設定も新しいパスワードにする。gMSA なら自動でそろう
パスワードを変えたが、古いパスワードを覚えたアプリやドライブの割り当てが残っている古いパスワードで何度も試され、アカウントがロックされる古い資格情報を使っている場所を探して直す
PC と DC の時刻がずれているKerberos の時刻の確認(5分)で失敗する時刻同期を直す
鍵を持つことが「本人」の証明

ここまで見てきたように、Windows の認証は「鍵を持っているかどうか」で本人を判断します。裏を返せば、パスワードや、パスワードから作った鍵は、どれも本人そのものと同じくらい大事な秘密だということです。コンピューターのパスワードが自動で定期的に変わるのも、gMSA がパスワードを自動で管理するのも、この秘密を長く同じままにしないための工夫です。

確認に使うコマンド

PC01(コマンドプロンプト):サインインしたユーザーが持っているチケット(TGT とサービスチケット)を表示する

klist

PC01(コマンドプロンプト・管理者):コンピューター(PC01$)が持っているチケットを表示する

klist -li 0x3e7

PC01(PowerShell・管理者):DC とのセキュアチャネルが正しく作れるかを確かめる

Test-ComputerSecureChannel -Verbose

PC01(コマンドプロンプト・管理者):セキュアチャネルの状態を確かめる

nltest /sc_verify:corp.example.com

PC01(PowerShell・管理者):コンピューターのパスワードを変更したときのイベント(5823)を表示する

Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='NETLOGON'; Id=5823} -MaxEvents 5

DC01(PowerShell・管理者):コンピューターとユーザーのパスワードを最後に変えた日時を表示する

Get-ADComputer PC01 -Properties PasswordLastSet | Select-Object Name, PasswordLastSet
Get-ADUser user01 -Properties PasswordLastSet | Select-Object Name, PasswordLastSet

まとめ

項目ひとことで
認証の正体同じ秘密を持つ2人が、秘密を見せずに「持っている」ことを示し合う
鍵の組み合わせいつも「アカウント と DC」。DC は全員の鍵を持ち、PC とサーバのあいだには共通の鍵がない
鍵がそろうときパスワードを決めたとき・変えたときだけ。ユーザーは入力から毎回計算、コンピューターは自分で30日ごとに変える
KerberosDC が「受け取る相手の鍵」で封をしたチケットを作り、PC はそれを運ぶ。サーバは自分の鍵で開けられれば本物と分かる
NTLMサーバは鍵を持たないので、DC に答え合わせを頼む
セキュアチャネルコンピューターと DC が問題を出し合い、おたがいを確かめてセッション鍵を作る
払い出すもの次の相手に見せるもの(チケット)と、その場限りの鍵(セッション鍵)。最後にサーバでアクセストークンができる

「〇〇認証」という名前がたくさんあっても、やっていることは「だれとだれが同じ鍵を持っていて、それをどう見せずに示すか」の組み合わせです。新しい認証の仕組みに出会ったときも、「この鍵はだれとだれが持っているのか」「何を確かめて、何を払い出しているのか」の2つを問いかけると、全体の流れがつかみやすくなります。

コメント