我们Tieto公司的MM专家在《程序员》第8期上发表了一篇关于DRM的文章,请大家指教。

DRM in Android

DRM,英文全称为Digital Rights Management,译为数字版权管理。它是目前业界使用非常广泛的一种数字内容版权保护技术。随着知识产权保护受重视的程度日益提高,快速攻城略地得Android智能手机是如何利用DRM来有效保护数字版权的呢?本文将通过剖析Android中的DRM框架以及相关工作流程来向读者揭示DRM的神秘面纱。

一  DRM架构介绍

严格来讲,DRM不是一项技术,而是一类技术。很多机构和联盟都提出过相应的DRM标准[1]。例如Open Mobile Alliance推出的OMA DRM、Marlin Developer Community提出的Marlin DRM,而Google则通过收购Widevine公司推出了Widevine DRM。

从Android智能终端来看,Google的原生Android(Android Open Source Project,简称AOSP)系统仅仅集成了OMA DRM V1的一部分功能,它远未构成一个完整的DRM解决方案。在这种情况下,设备厂商只能根据情况选择合适的DRM解决方案并集成到Android平台中来。例如,手机厂商可以通过Google的授权以获取Widevine DRM对应的软件包从而将Widevine DRM集成到自己的产品中。

为了方便设备厂商的集成,Android设计了一个通用的DRM软件框架,不同的DRM解决方案可通过Plugin的方式集成到Android系统中。图1所示为Android中的DRM软件架构。

图1  Android中DRM软件架构

由图1可知:

  • DRM Framework API模块是Framework层暴露给App的接口。该模块中最主要的类是DrmManagerClient。
  • DRM Framework API模块通过Binder机制和位于drmserver进程(以Android 4.1为例,drmserver的代码位于framework/av/drm/drmserver)中的DRM Manager模块通信。DRM Manager加载并管理系统中所有的DRM插件。
  • DRM Plugins是真正实现权限管理、数字内容解密等工作的模块。根据DRM标准的不同,这些Plugins的实现亦不相同。另外,一个手机可能会集成多个DRM Plugin。这是因为媒体文件如果采用不同的DRM解决方案进行加密的话,手机在播放它们时,DRM Manager需找到对应的DRM Plugin以进行解密。

图2所示为DRM架构中几个重要的类及其关系。

图2  Android中DRM架构中重要类图

由图2可知:

  • FileSource代表一个媒体文件。如果媒体文件中有DRM信息,它将创建一个DrmManagerClient对象。该对象用于处理媒体文件中和DRM相关的操作。DrmManagerClient内部通过DrmManagerClientImpl和位于drmserver进程中的DrmManagerService进行跨Binder通信。
  • MediaExtractor类封装了用于解析媒体文件中元数据的相关函数。对于DRM来说,系统会根据的DRM种类创建不同的MediaExtractor子类。和FileSource类似,MediaExtractor也通过DrmManagerClient和drmserver通信。
  • DrmManagerService运行于drmserver进程中,它是整个DRM框架的核心。DrmManagerService借助DrmManager管理系统中的DRM插件。
  • DRM插件必须实现IDrmEngine接口。为了方便开发者,Android提供了DrmEngineBase类,该类继承了IDrmEngine接口并实现了一些通用的接口函数。这样,DRM Plugin只需要从DrmEngineBase派生即可。
  • 如前文所述,DRM框架中真正完成DRM处理工作的是DRMPlugins,这些Plugins大都需要得到相关机构的授权后才能得到相应的专利代码包。图1中列出了三个DRM Plugin。其中FwdLockEngine(OMA-V1的Forward Lock)由AOSP提供。Marlin Plugin和WidevinePlugin则需要相关DRM机构提供专利代码包。

下面来看看Android中DRM的工作流程。

二  DRM工作流程介绍

2.1  DrmManagerService的初始化

DRM的工作流程和多媒体播放密切相关。首先来了解一下DrmManagerService的创建过程,相关流程如图3所示:

图3  DrmManagerService启动流程

由图3可知:

  • DrmManagerService实例对象由drmserver进程在main函数中调用instantiate创建。
  • DrmManagerService内部会创建一个DrmManager实例对象并调用loadPlugins来加载设备可能提供的DRM Plugin。DRM Plugin通过动态库的方式集成到设置中去。Android 4.1中有两个目录可存放DRM Plugin。一个是/vendor/lib/drm/,例如Widevine对应的libdrmwvmplugin.so一般放在这个目录中。另一个目录是/system/lib/drm/。每一个DRM Plugin对应为一个IDrmManager实例。所有被加载的DRM Plugin由DrmManager来统一管理。
  • DrmManagerService最后将通过addService把自己注册到Binder系统中以为广大客户端服务。

下面来介绍DRM的工作流程。Android支持的DRM播放方式分为两种:

  • 一种是基于基本码流的(Elementary Stream Based,简称ES Based)播放方式。目前Widevine DRM、Marline DRM都属于这一种类型。
  • 另一种是基于容器的(Container Base)播放方式,目前OMA DRM支持这种方法。

这两种不同的方式在播放流程上不尽相同。下文将以一个播放具有DRM保护的MP4文件为例,介绍DRM的工作流程。首先来看ES BasedDRM媒体播放工作流程

2.2  ES BasedDRM播放流程

ES Based DRM意味着每一个数据基元在播放时都需要解密。这种DRM的媒体文件或流可以使用普通方式正常读取,但读取出来的数据是经过加密的。如果不能对数据正确解密,那么该数据将无法正常播放。

在播放媒体文件之前,播放器首先要识别该文件是否被DRM保护。如果受DRM保护的话,还行初始化对应的DRM插件。这部分工作所涉及的流程如图4所示:

图4  ES BasedDRM插件初始化

由图4可知:

  • MediaExtractor首先通过sniff函数检查媒体内容的类型,然后创建相应的Extractor来分析数据。在DRM检查开启的情况下,SniffDRM函数就会被用来检查文件是否有DRM控制。
  • SniffDRM将调用DataSource中的DrmInitialization函数,从而在DataSource中创建一个DrmManagerClient实例。如此,MediaExtractor就将DataSource与DrmManagerService联系起来。
  • DrmInitialization函数非常重要,其主要工作包括:

(1)调用openDecryptSession,该函数内部会根据文件中的DRM信息来初始化正确的DRM Plugin(Widevine、OMV,还是其他DRM类型)。

(2)创建DecryptSession,并将DRM信息封装在DecryptHandler实例中传给FileSource。

  • DrmInitialization之后,SniffDRM会通过DecryptHandler来判断该文件是否有DRM控制,并分析出该DRM是ES Based,还是Container Based。如果属于ES Based DRM,MediaExtractor会创建一个DRMExtrator,而在DRMExtrator中,会创建一个MPEG4Extractor。

MediaExtrator创建完后,播放器即可开始播放。ES Based DRM播放相关流程如图5所示:

图5  ES Based的DRM媒体文件播放流程

图5所示的流程图可分为三个阶段:

  • 第一个阶段是资源初始化过程。该过程中,媒体播放器将通过getTrack以后获取一个媒体文件中代表媒体数据的DRMSource实例,DRMSource只负责DRM的控制和解密,而实际媒体数据的分析仍交给MPEG4Extractor来完成。对于播放器来说,它只和DRMExtrator和DRMSource交互。另外,在这一阶段中,initializeDecryptUnit函数将初始化解密相关的资源。
  • 第二阶段就是媒体数据读取,针对每一个数据基元,DRMExtrator都会先通过MPEG4Extractor取得未解密的原始数据,然后通过decrypt函数来请求DRM Plugin进行解密。解密后的数据会被放到另外一处缓存中供Codec使用。如果解密失败,decrypt将会返回错误,故播放器将无法解析这些数据。
  • 媒体播放完毕后将释放播放资源。和DRM相关的资源将由finalizeDecryptUnit来释放。

回顾上述流程,对ES Based DRM的特点是,不论用户是否有权限,播放器都能读取到媒体数据。

下面来看看Container Based DRM的播放流程。

2.3  Container Based DRM播放流程

和ES Based DRM截然不同的是Container Based DRM。受控于这种DRM管理的媒体文件在被读取时就会进行DRM的权限验证,如果验证失败,则无法从中读取到数据。故Container Based DRM最关键的是其pread接口,相关流程如图6所示:

图6  ContainerBasedDRM播放流程图

如图6可知:

  • 首先要进行的工作仍是判别数据格式和DRM类型并创建DrmManagerClient。这一过程和ES Based DRM流程相同,此处不拟赘述。
  • 接下来需创建MediaExtractor实例。与ES Based DRM不同的是,Container Based DRM在播放时无需创建DRMExtractor,而是直接创建MPEG4Extractor,并在该MediaExtractor中设定DRM的标识。
  • Container Based DRM关键在于pread函数。当MediaExtractor从FileSource中提取数据时,readAt最终通过DrmManagerClient的pread函数来访问DrmManager以从中读取数据。DrmManager将调用具体的DRMPlugin实现的pread。数据的权限检查和解密的工作都在该DRMPlugin完成。如果DRM解密失败,pread将不会得到数据。

上文介绍了Android平台中DRM播放的大体流程。下面来看看Google主推的Widevine DRM。

三  Widevine DRM介绍

2010年12月,Google不惜重金将视频数字版权管理软件公司Widevine招安。现在看来,Google的这一招为Android阵营增添了一员上将,有Widevine坐阵中军,Android就有实力在数字内容这片战场上与已故乔帮主的苹果一较高下。

在收购Widevine之前,Android没有系统的数字版权保护机制,而苹果则在iTunes、iPod时代就建立了完善的版权体系,这让很多内容提供商更愿意在iOS上发布自己的数字内容,从而使得iOS的生态系统更加丰富和成熟。Widevine的引入弥补了Android在这方面的短板,它是帮助Android成为当今移动OS霸主的功臣之一。

Android从3.0开始就支持Widevine,这距离Google收购Widevine仅仅过去了三个月,可见Google对于数字版权保护的迫切性。现在Widevine已经成为GMS(Google Mobile Service)中必备的内容,所有想要得到GMS的手机厂商,都需要根据GMS的要求搭载Widevine。

作为Google帐下的爱将,Google为支持Widevine也煞费苦心。目前Android平台中播放Widevine DRM媒体有两种方法:

  • 第一种方法和前文介绍的一样。Widevine DRM按照ES Based的流程进行播放。但和一般DRM不同的是,Widevine使用的Extractor是WVMExtractor,而不是DRMExtractor。
  • 第二种方法是MediaCodec模式,相关结构如图7所示。

图7  Widevine Crypto Plugin

由图7可知:

  • MediaCodec、MediaCrypto以Java API的形式直接暴露给应用层。这样,应用层能够控制解码、解密的过程。
  • Crypto Plugin是实际完成解密的模块,其结构和前文提到的DRM Plugin有所不同。

需要特别指出的是,Android目前对MediaCodec模式支持还不是很完善。根据笔者的试验,一些市面上流行的高端Android 4.1手机还不支持这种播放方式。

另外,Widevine的代码结构大体可分为三部分:

  • 第一部分是Android中的基本框架,包括WVMExtractor等。这部分代码在AOSP中都可以看到,属于Open Source的内容。这部分代码大多没有实质性内容,相关功能的实现封装在第二部分的专利代码包中。
  • 第二部分是Widevine的专利代码包。这部分代码需要得到Google授权后才能得到。该包提供了很多Widevine专用库用于完成Widevine DRM权限检查和解密。同时,它还提供了一些Sample App用于测试。
  • 第三部分是手机厂商自身的安全认证。Widevine是一个很强的版权控制体系,它甚至可在硬件层与厂商的安全机制绑定。很多知名的手机厂商都在boot等底层中加入自己的安全机制,只有通过可信赖的boot loader进行刷机才能得到具有正常权限的手机软件,并可以使用Widevine。这也是为什么很多破解的手机无法使用Widevine的原因。

由于专利代码包和厂商安全机制都涉及到版权问题,故本文就不拟对Widevine做进一步讨论了。如果厂商希望在自己的产品上也搭载Widevine,那么首先需要与Google联系。Google会提供Widevine的专业培训。

四  总结

本文主要讲述了Android中DRM的运行机制。事实上,DRM是一个不易触及的领域。由于其安全性高,保密性强,世界上真正掌握DRM核心技术的公司并不多。根据笔者的调查,DRM产业链中的相关者大概可分为如下三类:

  • 第一类是制定DRM标准的公司或机构,他们掌握DRM的核心技术,对外推广自己的DRM标准,为需要搭载DRM的公司提供支持。
  • 第二类是数字内容提供商,他们是最迫切应用DRM来保护自己数字版权的人,他们会向提供标准的公司够买DRM技术,在服务器端加密,并制定数字内容的买卖租赁机制以及相应的密钥配发原则。
  • 第三类是终端设备制造商,为了让自己的设备具有更广泛的应用性,他们需要搭载主流的DRM以适应市场需求,在搭载过程中,他们也需要标准公司的支持,拿到一些有专利的代码包,有时还会与内容提供商合作。当然,还有的时候,一家公司会担当其中的两个或全部角色,比如亚马逊,他即是内容提供商,提供电子书籍等内容,又是终端设备商,出品Kindle Fire这样的终端设备,这样做可以让他把内容和终端更好地整合在一起。

然而,国内DRM并不非常受欢迎。笔者对于国内的版权保护并无批评之意。只是由于国内数字内容发展的过程比较特殊,最终形成了当下这种以免费内容占主流的市场氛围和消费习惯。对于国内市场,任何一种强行主推DRM的收费模式的方法目前看起来还不合适。相信很多互联网巨头已经在其长期的摸索中体会了这一点。

当然这并不是说DRM在国内没有市场。目前很多公司在免费业务之上都加入了基于更高质量的收费业务,从而丰富了盈利的方式。更为重要的是,现在很多中国公司都在向国外扩张,而中国公司走到外面,就必须入乡随俗,遵从国外的游戏规则。这时,数字版权保护以及建立在其之上的DRM技术就成了一个必须要重视的问题。在此,笔者真心希望有一天国内能有更多优秀的公司走出国门,在中国模式和世界模式间找到平衡点,将我们自己的数字内容和终端产品推向世界。


[1]关于DRM的理论知识,读者可先参考http://en.wikipedia.org/wiki/Digital_rights_management

DRM in Android的更多相关文章

  1. DRM in Android详解--转

    DRM,英文全称为Digital Rights Management,译为数字版权管理.它是目前业界使用非常广泛的一种数字内容版权保护技术.随着知识产权保护受重视的程度日益提高,快速攻城略地得Andr ...

  2. Android软件测试Monkey测试工具

    前言: 最近开始研究Android自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括android测试框架.CTS.Monkey.Monkeyrunner.benchmark.其 ...

  3. Android系统在超级终端下必会的命令大全(adb shell命令大全)

    . 显示系统中全部Android平台: android list targets . 显示系统中全部AVD(模拟器): android list avd . 创建AVD(模拟器): android c ...

  4. Android Monkey测试

    Monkey测试1——Monkey的使用 原文地址: http://www.douban.com/note/257029872/ (转自豆瓣,版权属于豆瓣及豆瓣网友,如有冒犯请见谅并联系我们) Mon ...

  5. Android的多媒体框架OpenCore介绍

    网上资料很少, 不过还是找到一个比较详细的说明: 特地在此整理了下: 地址:http://blog.csdn.net/djy1992/article/details/9339787 分为几个阶段: 1 ...

  6. Android自动测试之Monkey工具

    Monkey工具 前言: 最 近开始研究Android自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括android测试框架.CTS.Monkey. Monkeyrunner. ...

  7. Android自动化测试手段之Monkey(adb shell monkey)

    一. 什么是Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实现对正在开发的应用程序 ...

  8. 【Android】自动测试工具 Monkey

    前言: 最近开始研究Android自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括android测试框架.CTS.Monkey.Monkeyrunner.benchmark.其 ...

  9. linux问题

    make:进入目录'/opt/FriendlyARM/tiny4412/05android/android-4.1.2'target Dex: framework trouble writing ou ...

随机推荐

  1. WCF:为 SharePoint 2010 Business Connectivity Services 构建 WCF Web 服务(第 1 部分,共 4 部分)

    转:http://msdn.microsoft.com/zh-cn/library/gg318615.aspx 摘要:通过此系列文章(共四部分)了解如何在 Microsoft SharePoint F ...

  2. 【转】ubuntu下自动挂载硬盘分区

    1, 首先摸清我系统的硬盘分区等使用情况 sudo fdisk -l Disk /dev/sda: 128.0 GB, 128035676160 bytes 255 heads, 63 sectors ...

  3. 25、BroadCastRecevier

    BroadCastRecevier 有两种注册方式 1. 清单文件里注册: 一旦应用程序被部署到手机, 广播接受者就会生效 2. 代码里面注册: 一旦代码所在的进程被杀死了, 广播接受者就失效了. 广 ...

  4. HDU 1024 Max Sum Plus Plus 简单DP

    这题的意思就是取m个连续的区间,使它们的和最大,下面就是建立状态转移方程 dp[i][j]表示已经有 i 个区间,最后一个区间的末尾是a[j] 那么dp[i][j]=max(dp[i][j-1]+a[ ...

  5. json解析之jackson ObjectMapper

    Json解析常用的有fastjson和jackson,性能上网上有不少的对比,说是fastjson比较好,今天先整理一下jackson的东西,后面再发一个fastjson的. jackson是spri ...

  6. 【译】 AWK教程指南 2概述

    2.1 为什么用AWK 由于awk具有上述特色,在问题处理的过程中,可轻易使用awk来撰写一些小工具:这些小工具并非用来解决整个大问题,它们只扮演解决个别问题过程的某些角色,可通过Shell所提供的p ...

  7. 编写安全代码:小心volatile的原子性误解

    本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载.但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途. ============ ...

  8. Linux PHP实现仿百度文库预览功能

    1.安装openoffice: tar zxvf OOo_3.3.0_Linux_x86-64_install-rpm-wJRE_zh-CN.tar.gzcd RPEMrpm -ivh *.rpm安装 ...

  9. cocos2d-x 3.0版本已经加了socket部分

    cocos2d-x开发者的福音到了,在3.0版本中新增了HttpClient.HttpRequest.SocketIO.Websocket库,需要网络交互的同学应该可以用到,并且它已经与cocos2d ...

  10. Java 8 开发顶级技巧

    本文由码农网 – 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 我使用Java 8编码已经有些年头,既用于新的应用程序,也用来迁移现有的应用,感觉是时候写一些我发现的非常有用的 ...