这篇文章上次修改于 515 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
2023/07/15 勘误
实际上借鉴widevine_eme_fingerprinting项目的做法并不能确定浏览器的唯一性
这是因为Chrome所使用的widevinecdm.dll每个版本(或者相邻的几个版本)都有一个相同的keybox
通过深入理解DRM(二)——了解Widevine与OEMCrypto可以知道,Device Id
就是keybox的一部分
即:每个keybox都有唯一的Device Id
,但是widevinecdm.dll大家用的都一样,所以同版本的widevinecdm.dll下,按照widevine_eme_fingerprinting的方法拿到的Device Id
自然是一样的。
感谢eddie的指正!
注:Device Id
也就是Serial Number
Ref: Widevine Partner License SDK v4.3.4.pdf
这是windows chrome的请求,解析可以知道USER_DEVICE
的SerialNumber
就是后文获取的Cert Serial Number
>>> "\352\021\365K\036\014f\263\363\014>t\251\235VF".encode('latin-1').hex()
'ea11f54b1e0c66b3f30c3e74a99d5646'
这是Android上的,注意这里的ServiceCertificateSerialNumber
是服务端证书的,对应的是widevine_eme_fingerprinting/script_eme_full.js的serverCert ,即安卓上该方法不适用(目前看来)
>>> "\027\005\271\027\314\022\004\206\213\0063:/w*\214".encode('latin-1').hex()
'1705b917cc1204868b06333a2f772a8c'
也许有人想知道这个怎么解析的
import wv_proto2_pb2 as wv_proto2
resp = bytes.fromhex('...')
license_resp = wv_proto2.SignedLicenseRequest()
license_resp.ParseFromString(resp)
print(license_resp)
还需要补充说明的是,根据文档说明device id确实是唯一的,但是这是对应于每一个keybox来说的,但这通常需要的设备具有TEE之类的功能,比如这里有很多keybox,可以看到device id都是不同的,即每个设备唯一
原文
widevine通常用来做drm授权,具体能做什么还请自己查询资料
其工作原理简单来说就是:客户端内置一个RSA私钥,当然这个私钥通常是白盒实现或者存放在安全可信的硬件中,然后通过一系列的加解密,和授权服务器交互数据实现DRM物料的加密key的交换
当然其中的过程还是相当复杂的,总而言之很难把私钥搞到,即使搞到了,widevine官方也会很快下发新版本然后revoke这个私钥
在上述提到的授权及交换数据的过程中,会涉及到客户端的唯一标识符,也就是要确定客户端的唯一性(要不然怎么鉴权)
现代浏览器基本上都对widevine做了支持,同时也提供了一个叫EME的接口,在客户端可以通过该接口记录一些数据交换的信息
通过EME的接口,我们可以拿到一些关键性的数据,这里恰好有一个项目可以向你演示如何通过EME记录授权过程的关键数据获取:
先搞一个服务器,要https域名,把html放上去;搞定之后直接访问你的域名+index.html
然后你可以在console中看到一些日志,其中有什么company_name的这一条,复制下来
然后转成二进制保存,用项目中的utils/get_device_info.py做下信息提取
然后你就能得到这样的结果,这里的Cert Serial Number
就是你电脑浏览器的唯一标识符了,即使你使用隐身模式也不会改变
那么这个我们怎么拿来为己所用呢?
简单来说就是你可以在记录之后,传到自己的服务器上,收集这个信息
你说客户端可以篡改这个消息?不怕,我们可以在收集到这个信息之后做验证
怎么操作呢?答案很简单:重放
通过抓包可以知道刚才那个log打印出来的就是这个请求的payload
我们尝试修改Cert Serial Number
的内容进行重放会发生什么?
如图,如果改变了原来的Cert Serial Number
部分,响应将会出现INVALID_LICENSE_CHALLENGE
也就是说如果客户端想伪造这个Cert Serial Number
部分,那么我们可以检查出来
你可能想问Cert Serial Number
部分之外的部分一起修改,有没有可能变成合法的?
答案是:当然可以,但前提条件是你把客户端的私钥搞出来,再做一系列的签名运算
前面也说了:
私钥通常是白盒实现或者存放在安全可信的硬件中
一般人真搞不出来:)
总结:
- 借助EME记录关键的信息,上传自己的服务端
- 在自己的服务端重放请求,确定payload合法性
- 从payload中提取
Cert Serial Number
作为客户端唯一标识
已有 5 条评论
麻烦问下,你这个测试是在PC上测试的还是在手机设备的Chrome浏览器上测试的?我这边验证发现再Mac系统的Chrome Firefox上是有设备指纹信息的,手机设备的Chrome中无这个设备指纹信息
我在多个电脑的浏览器上测试,设备指纹对应的值是一样的,这几个电脑都是mac arm系统,widevine_cdm_version 4.10.2557.02版本也是一样,设备指纹都相同(都是B9 11 4F 03 FD 0D 8D A8 70 1C 5B 45 A6 0D 62 91),感觉这个不是设备指纹,而是特定widevine_cdm_version的标识
我在一个window电脑上获取的设备指纹信息和你的文章中的信息是一样的,初步推测这个信息是特定widevine_cdm_version版本下,不同CPU架构下(architecture_name)唯一标识,非浏览器设备指纹
@eddie 感谢您的指正,device id实际上是一个keybox唯一,widevinecdm.dll大家都通用,所以自然是一样的。不过对于widevine L1设备,它们的keybox都不一样,device id也会不一样,是具有唯一性的。当然目前应该是没法通过浏览器就能获取到L1设备的device id的;相关补充已经添加到文章中,再次感谢!
Please contact me via email . i want you to setup this on my server .