Jimmy's blog

TCL, DOCSIS 測試筆記

DOCSIS BPI 解密 - 取得 TEK

| Comments

簡介

DOCSIS 1.0 BPI 加密使用的是 DES,為了能解開封包內容必須先取得 TEK (raffic Encryption Key)。取得 TEK 是透過 BPKM (Baseline Privacy Key Management) Protocol。 BPKM 的過程中 CMTS 會使用 RSA 加密 Auth Key,CM 解開 Auth Key 後算出 KEK (Key Encryption Key),接著再用 KEK 解開 TEK,之後就能用 TEK 進行加密。

以下範例出自 DOCSIS 1.0 Baseline Privacy Interface Specification,擷取到 DOCSIS 封包後只要擁有 CM 的 private key,透過一些操作就能解開封包內容

此範例所用的 private key 如下

cm_private_key
1
2
3
4
5
6
7
8
9
10
11
12
13
-----BEGIN PRIVATE KEY-----
MIIB5gIBADANBgkqhkiG9w0BAQEFAASCAdAwggHMAgEAAmEA0/SEuCPOcDXnqzIw
QxP//xsmwvh/5uUPIprtgBPYHZW0MIfwtatQ3rHYgrJCqWcz2eXCsSoNQliUYwsR
DqBVlrHPwH8Ul0a8RBNLXkreRs7ryLY1imabM8IjdfXIaXllAgMBAAECYQCTQM6w
C5hRlvGzm3OyNoPk3R0p2XEqnbrNJOuZzq+XpjkAeoE+BZ5yiQZNjsEHZj146Wd9
q+Xo80xwTlz++xUljzdU7doBjsje/mD1ob3obE/FcWGmb6dVySnYyovxxYUCMQDx
IR7RSf+VM+Vg3kyurvZ1EYuW1UVFlu6Ioz3ZoRdmQq51e8YYCg14ObVemRbGLdsC
MQDhBs3QCMkVCRSTioyl14S4VhVCOLfnjonL1lafWXYgEH9ebuHD6jFBkOCOJEde
ub8CMQC/v+rV29aXO9Gomp64OwJaTj2HEMopcMD3f3jr26LT+yro2ijJbRURCjMk
qvDlYAkCMDIClhkG6tGO/BCyOQHefPOOxhi6jDydFAjGMOgnNLZ5lCUDlY857Ap7
TTyp2Wa29wIxAJV1icfFAoGlWRmP+soKv7iNG8m5efvRTx+zyjIw19FY7QRkxTWy
2yGB77D9b/FjJw==
-----END PRIVATE KEY-----

DOCSIS 1.0 時沒有使用 certificate 來驗證 CM 的身份,只用了 RSA 加密,所以只要修改 CM mac address,就能冒充其他 CM, DOCSIS 1.1 BPI+ 就加上 certificate,這樣就無法輕易假冒其他 CM 了。

BPKM Protocol

順利的話 BPKM 要 4 個步驟:Auth Request, Auth Reply, Key Request, 以及 Key Reply。

Auth Request

首先,當 CM 註冊完且需要開啟 BPI 時會送出 Auth Request,內容包含一些基本資訊以及最重要的 RSA Public Key

Auth Reply

CMTS 收到 Auth Request 後會產生一把 Auth Key,把 Auth Key 利用 CM 的 RSA Public Key 加密後透過 Auth Reply 傳給 CM。

Auth Key 中的 0x07 是 Identifier, 0x0060 是長度 (96 bytes),真正的資料是 0xce7f8efe … 3ac4c480

DOCSIS 1.0 用的 RSA key 比較短,這個範例中用的是 768 bits,所以加密後的 Auth Key 是 96 bytes。

可以利用 OpenSSL 把這段資料解密

1
2
openssl rsautl -in auth_key -inkey cm_private_key -decrypt -hexdump
0000 - 3b d5 50 60 bd a2 57 c0-                          ;.P`..W.

解出來 auth key 是 0x3bd55060bda257c0,利用 auth key 再算出之後步驟要用到的 3 個值,Key Encryption Key, upstream Message Authentication Key, downstream Message Authentication Key。

這 3 把 key 算法都是透過 sha1

  1. Key Encryption Key
    在 auth key 前補上 64 個 0x53 後計算 sha1,再取前 8 bytes 當作 KEK

  2. upstream Message Authentication Key
    在 auth key 前補上 64 個 0x5c 後計算 sha1

  3. downstream Message Authentication Key
    在 auth key 前補上 64 個 0x3a 後計算 sha1

利用 tcl 計算

calckek.tcl
1
2
3
4
5
6
7
8
9
package require sha1
set auth_key [binary format H* 3bd55060bda257c0]
set KEK [string range [sha1::sha1 -hex [string repeat \x53 64]$auth_key] 0 15]
set UAK [sha1::sha1 -hex [string repeat \x5c 64]$auth_key]
set DAK [sha1::sha1 -hex [string repeat \x3a 64]$auth_key]

puts "Key Encryption Key: $KEK"
puts "upstream Message Authentication Key: $UAK"
puts "downstream Message Authentication Key: $DAK"

結果為

1
2
3
Key Encryption Key: 5f59051d9217d983
upstream Message Authentication Key: ebff98cd5cd457bbfd12b565ffaaf689d4982614
downstream Message Authentication Key: 5e4769839eeee4d004a4c12380b05ad18ac92c9c

Key Request

接著 CM 送出 key request,除了一些 CM 的基本資訊外還有在 auth reply 取得的 Key Sequence Number,最後會補上 HMAC digest

這個 HMAC digest 是利用 upstream Message Authentication Key 計算 Key Request 封包,從 Key Request Header 到 SID (0x0773…0c00022260),使用的演算法是 HMAC-SHA-1

CMTS 可以透過這個方式驗證送出 key request 的 CM,因為這個 key 是由 auth key 算出來的,而 auth key 是透過 RSA public key加密,只有擁有該 private key 的 CM 能送出正確的封包。

Key Reply

最後 CMTS 確認完 Key Request 沒問題後就把之後要用的 TEK 利用 KEK 加密後送出,這邊使用的演算法是 DES-ECB

與 key request 類似, key reply 也有一個 HMAC digest 讓 CM 驗證

使用 OpenSSL 解密

1
2
3
echo -n -e "\xab\xb9\xd6\x03\x23\x86\xdb\xce" > tek
openssl des-ecb -in tek -d -nopad -K 5f59051d9217d983 | hexdump -C
00000000  e6 60 0f d8 85 2e f5 ab                           |.`......|

tcl 有 tclDES 可以用來解密

1
2
3
4
5
package require tclDES
set keyset [::des::keyset create [binary format H* 5f59051d9217d983]]
set tek [::des::decrypt $keyset \xab\xb9\xd6\x03\x23\x86\xdb\xce ecb]
binary scan $tek H* TEK
puts TEK=$TEK

最後算出來的值為 0xe6600fd8852ef5ab,取得 TEK 後就能解開加密的封包了。

Comments