環境
【構成図】

ミラーポートを作成したスイッチにPCを接続し、パケットキャプチャしている
【使用機材】
| 種類 | 型番 | メーカ |
|---|---|---|
| PBX | asterisk | |
| IP電話 | IP-4H-CT009S | HITACHI |
| PoE | EHB-UG2B05-PL | ELECOM |
| スイッチ | GS105E | NETGEAR |
【設定情報】
- IPアドレス
| 端末 | アドレス |
|---|---|
| PBX | 192.168.0.1 |
| 電話A | 192.168.0.100 |
| 電話B | 192.168.0.101 |
- 認証情報
| 項目 | 電話A | 電話B |
|---|---|---|
| 内線番号 | 100 | 101 |
| ユーザID | 100 | 101 |
| パスワード | pass100 | pass101 |
認証パケット
「SIP Digest認証」に使用されているパケットは4つ。

①Client → Server 「Request」
IP電話機がSIPサーバへ
「私は内線100です。このIPアドレスで待ち受けています」
と通知するためのパケット。
この時点では認証情報は含まれておらず、端末情報や連絡先情報のみが送信される。
REGISTER sip:192.168.0.1 SIP/2.0
CSeq: 123572333 REGISTER
Via: SIP/2.0/UDP 192.168.0.100:5060;branch=z9hG4bKC62058CD
Expires: 3600
From: <sip:100@192.168.0.1>;tag=1468214362
Call-ID: 809bbea0-0be-d311-9960-0d0ec6041f3@192.168.0.100
To: <sip:100@192.168.0.1>
Contact: <sip:100@192.168.0.100>
Content-Length: 0
User-Agent: IP-4H-CT009S Z019 00D0EC6041F3
Max-Forwards: 70
このパケットの段階ではサーバに送信する情報はまだ少ない。
- Contactヘッダ
- 内線番号
- 端末のIP
- Call-ID etc...
【Contactヘッダ】
Contact: <sip:100@192.168.0.100>
SIPサーバはこの情報を利用して
内線100 → 192.168.0.100
※性格にはURIで保存される
という対応表を作成する。
他の端末が内線100へ発信した際、SIPサーバはこの情報を参照してINVITEを転送する。
【Call-ID】
IP電話の端末側で生成される、このREGISTERトランザクションの識別子。
WireSharkでSIPストリームを負うときはこのCall-IDを使用して絞り込む
sip.Call-ID == "809bbea0-0be-d311-9960-0d0ec6041f3@192.168.0.100"
②Server → Client 「401チャレンジ」
クライアントからユーザ名などの情報は受け取ったが、パスワードが確認できないため認証できない状態。
そこでサーバは nonce(使い捨てのランダム値) をクライアントへ送信する。
クライアントは
- ユーザ名
- realm
- パスワード
- nonce
- SIPメソッド(REGISTER など)
- URI
を用いて Digest認証値(response) を計算し、次回のREGISTERに含めて送信する。
サーバは同じ計算を行い、結果が一致すれば認証成功となる。
401 Unauthorized は認証失敗を意味するわけではない。
Digest認証では、認証に必要な nonce をクライアントへ渡すためのチャレンジ応答として利用される。
通信自体は暗号化されていないが、パスワードそのものはネットワーク上を流れないため、盗聴されても即座にパスワードが漏洩することはない。(計算方法は後述)
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.0.100:5060;rport=5060;received=192.168.0.100;branch=z9hG4bKC62058CD
Call-ID: 809bbea0-0be-d311-9960-0d0ec6041f3@192.168.0.100
From: <sip:100@192.168.0.1>;tag=1468214362
To: <sip:100@192.168.0.1>;tag=z9hG4bKC62058CD
CSeq: 123572333 REGISTER
WWW-Authenticate: Digest realm="asterisk",nonce="1780998145/c3ae9090a9ef5aa1093a478a6011f57e",opaque="722ece1366142553",algorithm=MD5,qop="auth"
Server: Asterisk PBX 22.9.0
Content-Length: 0
【認証方式】
以下の部分から、認証方式が判明する。
WWW-Authenticate: Digest
他にも、「IP認証(認証なし)」「OAuth」「Mutual TLS(証明書)」「Basic認証」等、様々な方式があるらしい。
【nonce】
今回のパケットで一番重要な部分
クライアントが「認証情報の計算」に使用する大事な情報を送信している
realm="asterisk",nonce="1780998145/c3ae9090a9ef5aa1093a478a6011f57e",opaque="722ece1366142553",algorithm=MD5,qop="auth"
- realm
認証領域(Authentication Realm)。 - nonce
サーバが発行したチャレンジ値。
今回使用しているPBXの「Asterisk PBX 22.9.0」では、nonceの構造が以下の様な形になっている。
/(スラッシュ)の前の1780998145の部分はUNIX時間であり、変換してみると筆者がこのパケットをキャプチャした時間がわかる。
後半部分はランダム値、またはサーバ内部情報から生成されたハッシュ値と考えられる。
- opaque
この値はサーバ側の都合で付与している。クライアントは何も考えずにそのまま返すだけである。 - algorithm
ハッシュ関数の指定をしている。SIPでは今でもMD5が多いみたい。
③Client → Server 「Request(再)」
サーバから受け取った情報をもとに、やっと認証情報を送信できる。
REGISTER sip:192.168.0.1 SIP/2.0
CSeq: 123572334 REGISTER
Via: SIP/2.0/UDP 192.168.0.100:5060;branch=z9hG4bK2B8A64D3
Expires: 3600
Authorization: Digest username="100", realm="asterisk", nonce="1780998145/c3ae9090a9ef5aa1093a478a6011f57e", uri="sip:192.168.0.1", response="eaad5e48e0478af03206308862f930b1", algorithm=md5, cnonce="df311abb", qop=auth, nc=00000001, opaque="722ece1366142553"
From: <sip:100@192.168.0.1>;tag=4053797898
Call-ID: 809bbea0-0be-d311-9960-0d0ec6041f3@192.168.0.100
To: <sip:100@192.168.0.1>
Contact: <sip:100@192.168.0.100>
Content-Length: 0
User-Agent: IP-4H-CT009S Z019 00D0EC6041F3
Max-Forwards: 70
【計算をやってみる!!】
1️⃣ HA1の生成
HA1の構造は以下の通り
HA1 = MD5(username:realm:password)
実際の値を当てはめて計算すると、、、
HA1 = MD5(100:asterisk:pass100) = 7159abd3b45ac9c75cbf18a8bd3994df
2️⃣ HA2の生成
HA2の構造は以下の通り
HA2 = MD5(method:uri)
今回はREGISTERなので以下のようになる
HA2 = MD5(REGISTER:sip:192.168.0.1) = 6c366630c35578ca4142c7f9f34632d8
3️⃣ responseの生成
response = MD5(HA1:nonce:nc:cnonce:qop:HA2)
当てはめてみると、
response = MD5(7159abd3b45ac9c75cbf18a8bd3994df:1780998145/c3ae9090a9ef5aa1093a478a6011f57e:00000001:df311abb:auth:6c366630c35578ca4142c7f9f34632d8)
= eaad5e48e0478af03206308862f930b1
実際のパケットと値が正しいことがわかる
④Server → Client 「成功」
このパケットは「認証情報を検証した結果、ユーザー100の登録を受け付けました」という意味。
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.100:5060;rport=5060;received=192.168.0.100;branch=z9hG4bK2B8A64D3
Call-ID: 809bbea0-0be-d311-9960-0d0ec6041f3@192.168.0.100
From: <sip:100@192.168.0.1>;tag=4053797898
To: <sip:100@192.168.0.1>;tag=z9hG4bK2B8A64D3
CSeq: 123572334 REGISTER
Date: Tue, 09 Jun 2026 09:42:25 GMT
Contact: <sip:100@192.168.0.100>;expires=3599
Expires: 3600
Server: Asterisk PBX 22.9.0
Content-Length: 0
nonceを使用した認証情報を含む計算をサーバでも検証し、クライアントから送られてきた値と同じであれば認証成功であり、このパケットが送信される。
Asteriskはこの情報をLocation Serviceへ登録し、
他端末から内線100へ着信があった場合の転送先として利用する。