实现联通 IPTV 认证
参考中国联通家庭宽带多媒体应用平台技术规范与盒端接口分册。 虽然各地区的实现基本上都仍然是不规范的, 但相比网上的说法已经改了一些地方。
整体流程可以参考这篇文章, 有些流程相对有出入,具体如下。
STB 登录
function getSTBAuthenticator()
{
document.authform.STBID.value = Authentication.CTCGetConfig("STBID");
var EncryptToken = "................................";
document.authform.Authenticator.value = Authentication.CTCGetAuthInfo(EncryptToken);
document.authform.userToken.value = "................................";
document.authform.mac.value = Authentication.CTCGetConfig("mac");
}
这里 CTCGetAuthInfo 仍然是只有 8 位,同样退化成了 DES ,但值的范围可能不一样。
密码的内容可以直接 HMW_config_read("Iptv.Password", pBuf, bufSize); 。
重新加密的方法:
def des_encrypt_ecb(key, plaintext):
cipher = DES.new(key, DES.MODE_ECB)
padded_plaintext = pad(plaintext.encode('utf-8'), DES.block_size)
encrypted_bytes = cipher.encrypt(padded_plaintext)
return binascii.hexlify(encrypted_bytes).decode('utf-8')
des_encrypt_ecb(key, f'99999${EncryToken}${UserID}${STBID}${IP}${MAC}$$CTC')
注意这里的 random ,在某些配置下只会用默认值,也就是 99999 ,用随机值反而不对。
tempkey 的算法
md5(hashCode(SESSIONID + 标识符 + MAC地址))。
MAC地址加冒号、大写。 标识符是写死的,除非系统升级可能会变。 hashCode 是 Java 同款的 String.hashCode 。
所以计算代码如下:
from hashlib import md5
from functools import reduce
def calc_key(a, c):
h = lambda s, v=0: reduce(lambda x, y: (x * 31 + ord(y)) & 4294967295, s, v)
u = h(c, h(a) * 0xcdaa61c1 + 0x870f92bc)
k = (u + 2**31) % 2**32 - 2**31
return md5(str(k).encode()).hexdigest().upper()
if __name__ == '__main__':
session_id = '00000000000000000000000000000000'
mac_addr = '00:AA:BB:CC:DD:EE'
print(calc_key(session_id, mac_addr))