簡介
在DOCSIS BPI 解密 - 取得 TEK中已經把 TEK 解出來,接下來只要使用對的的演算法就能解開加密的封包了。 延續之前的範例,用 Key Reply 裡的參數來解密
加解密參數
Key Reply 的內容為 其中用來加解密的 key 為 TEK 以及 IV,此範例中 TEK=0xe6600fd8852ef5ab IV=0x810e528e1c5fda1a 其他參數用來指示這組 key 能用多久以及提供一個序號,在 DOCSIS 封包的 header 裡會帶有這個序號標示使用的是那一組 key。 真正被加密的部份只有 Packet PDU (Layer 2 Ethernet frame) 中 DA (destination MAC) SA (source MAC) 之後的內容。以下只探討 Packet PDU 的部份。
加密演算法
加密 PDU 使用的是 DES,這是一種 Block cipher 有多種工作模式,DES 使用的 block size 為 8 bytes,DOCSIS BPI 用了 CBC 和 CFB 這兩種工作模式。 由於封包長度不固定,但是使用這種加密方式輸入必須要是 8 bytes 的整數倍,所以會用 2 種工作模式來處理。
CBC only
若要加密的內容正好是 8 bytes 的整數倍,直接使用 DES-CBC 加密 若輸入為
DA | 01 02 03 04 05 06 |
SA | f1 f2 f3 f4 f5 f6 |
Type/Len | 00 01 |
User Data | 02 03 04 05 06 07 08 09 0a 0b |
CRC | 88 41 65 06 |
則加密後會變成
DA | 01 02 03 04 05 06 |
SA | f1 f2 f3 f4 f5 f6 |
Type/Len | 0d da |
User Data | 5a cb d0 5e 55 67 9f 04 d1 b6 |
CRC | 41 3d 4e ed |
使用 tcl 解密
1 2 3 4 5 6 7 |
|
plaintext=000102030405060708090a0b88416506
CBC + CFB
若要加密的內容大於 8 bytes 但不是 8 bytes 的整數倍要分成兩段加密,第一部份是 8 bytes 的整數倍使用 CBC,剩餘的部份使用 CFB。 若輸入為
DA | 01 02 03 04 05 06 |
SA | f1 f2 f3 f4 f5 f6 |
Type/Len | 00 01 |
User Data | 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e |
CRC | 91 d2 d1 9f |
則加密後會變成
DA | 01 02 03 04 05 06 |
SA | f1 f2 f3 f4 f5 f6 |
Type/Len | 0d 0a |
User Data | 5a cb d0 5e 55 67 51 47 46 86 8a 71 e5 |
CRC | 77 ef ac 88 |
首先是 CBC 的部份,和之前作法相同,要加密的資料是 0x0001…0e91 這 16 bytes,剩下的 3 bytes 0xd2d19f 要特別處理,因為 DES 要輸入 8 bytes 整數倍,所以先補 0x00 補到 8 bytes, 接著再用 DES-CFB 加密 (此時使用的 key 不變,IV 換成 CBC 密文區塊中的最後 8 bytes),加密完後載取出前 3 bytes 即可,透過照種方式就能讓加密前後的資料長度維持不變。
同樣使用 tcl 解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
plaintext=000102030405060708090a0b0c0d0e91
plaintext=d2d19f
CFB only
若要加密的內容小於 8 bytes,就使用 DES-CFB,key 和 IV 使用 key reply 取得的資訊, 若輸入為
DA | 01 02 03 04 05 06 |
SA | f1 f2 f3 f4 f5 f6 |
Type/Len | 00 01 |
User Data | 02 |
CRC | 88 ee 59 7e |
加密後會變成
DA | 01 02 03 04 05 06 |
SA | f1 f2 f3 f4 f5 f6 |
Type/Len | 17 86 |
User Data | a8 |
CRC | 03 a0 85 75 |
1 2 3 4 5 6 7 8 |
|
plaintext=00010288ee597e
CRC
解密完後可以算一下 CRC 來驗證有沒有算錯,CRC 計算範圍是 Ethernet frame 扣除 CRC 4 bytes,以最後這個 CFB only 的範例來看
inputt = 0x010203040506f1f2f3f4f5f6000102
1 2 3 4 |
|
CRC=88ee597e