簡介
在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 解密
package require tclDES set iv [binary format H* 810e528e1c5fda1a] set keyset [::des::keyset create [binary format H* e6600fd8852ef5ab]] set cipher [binary format H* 0dda5acbd05e55679f04d1b6413d4eed ] set plain [::des::decrypt $keyset $cipher cbc iv] binary scan $plain H* plain puts plaintext=$plain
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 解密
package require tclDES # CBC 區塊 set iv [binary format H* 810e528e1c5fda1a] set keyset [::des::keyset create [binary format H* e6600fd8852ef5ab]] set cipher [binary format H* 0dda5acbd05e5567514746868a71e577] set plain [::des::decrypt $keyset $cipher cbc iv] binary scan $plain H* plain puts plaintext=$plain # CFB 區塊 set iv [binary format H* 514746868a71e577] ; # IV 要換掉 set keyset [::des::keyset create [binary format H* e6600fd8852ef5ab]] # CFB 工作模式的特性,解密時後面亂填不影響真正要的部份,這邊補0x00 set cipher [binary format H* efac880000000000] set plain [string range [::des::decrypt $keyset $cipher cfb iv] 0 2] binary scan $plain H* plain puts plaintext=$plain
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 |
package require tclDES set iv [binary format H* 810e528e1c5fda1a] set keyset [::des::keyset create [binary format H* e6600fd8852ef5ab]] # 資料只有 7 bytes, 補一個 00 set cipher [binary format H* 1786a803a0857500] set plain [string range [::des::decrypt $keyset $cipher cfb iv] 0 6] binary scan $plain H* plain puts plaintext=$plain
plaintext=00010288ee597e
CRC
解密完後可以算一下 CRC 來驗證有沒有算錯,CRC 計算範圍是 Ethernet frame 扣除 CRC 4 bytes,以最後這個 CFB only 的範例來看
inputt = 0x010203040506f1f2f3f4f5f6000102
package require crc32 set crc [crc::crc32 [binary format H* 010203040506f1f2f3f4f5f6000102]] binary scan [binary format i $crc] H* CRC puts CRC=$CRC
CRC=88ee597e
沒有留言:
張貼留言