DRM标准学习笔记2-ForwardLock原理及实现
1. ForwardLock
- ForwardLock 是DRM1.0中最简单的一种传输方式。请参考DRM标准学习笔记1
2. ForwardLock工作流程
- 用特定工具,或者是手动编写,将一个普通的视频文件(例如mp4) 生成一个符合标准的DRM文件,放到服务器上;
- 用户付费后,用下载工具将此DRM文件下载到本地;
- 下载工具必须支持这种DRM文件,下载的时候,其内部实际上是把此DRM文件进行了加密,加密算法可以采用AES等算法。密钥应该是每台机器生成一个唯一的密钥,加密和解密密钥是相同的。
- 这样,在本地端就有了一个加密的媒体文件,用户可以在本机上进行播放,但如果COPY到另外的机器上,由于密钥不同,所以不以成功解密,这样就达到了ForwardLock的目的。
3. 符合ForwardLocak标准的DRM文件格式
-
如下所示的格式:
--boundary12345\r\n Content-type: video/mp4\r\n Content-Transfer-Encoding: binary\r\n \r\n . . .\r\n --boundary12345--\r\n
-
说明:
- DRM文件格式其实就是在原始的媒体文件加了一个头和一个尾。如上所示。
- 头一共增加了四行,在这里我把隐藏字符也用转义字写出来,目的就是为了看清楚。
- 第一行是以--开头,后跟一个随机的字符串,但结尾时也必须是这个字符串。然后是回车换行。
- 第二行是说明此文件的mime type是什么
- 第三行说的是编码格式,是二进制,还是64 base。
- 第四行是一个空行。
- 然后是原始的媒体文件,这里用三个点的三行来进行表示。
- 最后,在原始文件的末尾先来一个回车换行
- 最后一行是以--开头和结尾,中间放上跟头一样的字符串,回车换行。
4. Android中如何实现ForwardLocak?
- 最后,目前的Android代码(Android4.1JB)是支持此功能的,即通过Browser下载的时候,如果是FrowardLocak文件则会进行文件的加密。
-
如果想自己写一个来玩玩,可以用以下的代码实现:
mDrmManagerClient = new DrmManagerClient(); mConvertSessionID = mDrmManagerClient->openConvertSession(s_imetype); ... DrmBuffer buffer((char *)data, (int)size); DrmConvertedStatus *convertedStatus = mDrmManagerClient->convertData(mConvertSessionID, &buffer); int write_len = writeConvertedStatusToFile(convertedStatus, mDrmOffset + offset); ... // close drm session and write drm file size. convertedStatus = mDrmManagerClient->closeConvertSession(mConvertSessionID); writeConvertedStatusToFile(convertedStatus); // delete the instance. delete mDrmManagerClient; mDrmManagerClient=NULL;
-
说明:
- writeConvertedStatusToFile是我写的一个处理转换结果的私有函数,主要是把结果convertedStatus中的数据进行保存。
- 在最后,关闭ConvertSession后,还会返回一个convertedStatus,这里边也包含数据,并且多包含了一个offset,位置正好位于头部,这里存的是整个文件的大小,因为大小只有在整个转换完成,关闭时才会知道。
- 另外,如果想对一个普通的媒体文件进行加密,则需要自己加上DRM的头和尾然后用此类的实例进行转换。
5. Android中DRM代码结构分析
-
代码位置
-
frameworks/base/drm/ (DRM的Java和JNI代码)
- java/
- jni/
-
frameworks/av/drm/ (DRM的Native层代码,包括引擎和服务)
- common/
- drmserver/
-
libdrmframework/
- DrmManagerClient.cpp
- include/
- plugins/
-
frameworks/base/media/ (此路径中有关DRM的代码可能是遗留代码,目前还不知道有什么用)
- libdrm/mobile1/
- java/drm/
-
frameworks/base/drm/ (DRM的Java和JNI代码)