导语
为了保障视频内容安全,防止视频被非法下载和传播,对象存储(Cloud Object Storage,COS)数据处理基于数据万象 CI 提供了 HLS 视频加密的功能,拥有相比于私有读文件更高的安全级别。加密后的视频,无法分发给无访问权限的用户观看。即使视频被下载到本地,视频本身也是被加密的,无法正常播放和二次分发,从而保障您的视频版权不受到非法侵犯。
本文基于 COS 数据工作流,对视频进行 HLS 转码加密,同时搭建一套基础的密钥管理服务,并利用腾讯云超级播放器,播放加密后的视频文件。
一. 方案对比
说到视频加密,可能会有同学有这样的疑问图片:咦,存在 COS 上的文件不是可以设置成私有读么,再结合防盗链功能,这不是已经很安全了,那我为什么还要多此一举,来对视频进行加密呢?
这位同学的这个问题问得非常好,没错,私有读写权限、防盗链功能、以及本期的主角视频加密功能,它们三者的关系非常微妙,既有相似之处,又截然不同。接下来且听我细细剖析,从概念和具体的使用场景对比三者之间的不同之处。
1.1 私有读写权限
私有读写权限是存储桶的三大公共权限(私有读写、公有读私有写和公有读写)之一,只有该存储桶的创建者及有授权的账号才对该存储桶中的对象有读写权限,其他任何人对该存储桶中的对象都没有读写权限。存储桶访问权限默认为私有读写,也是推荐使用的访问权限。
相比公有读文件,私有读文件不可匿名访问,访问时必须携带签名,适用于较私密,只提供给指定账号访问的场景,安全性也相对较高。
1.2 防盗链功能
腾讯云对象存储支持防盗链配置,用户可以对存储桶设置防盗链功能,该功能可以实现对访问来源设置黑、白名单,避免资源被盗用。
其原理是通过请求 Header 里的 Referer 地址来进行判断,当浏览器向 Web 服务器发送请求的时候,一般会带上 Referer,告诉服务器该请求是从哪个页面链接过来的,服务器就可以禁止或允许某些来源的网站访问资源。实现对访客的身份识别和过滤,防止网站资源被非法盗用,给用户带来不必要的损失。
1.3 视频加密功能
对于公开的视频文件,我们无法通过设置私有读写权限或防盗链功能来确保文件的所有权不受侵犯,因为用户可以直接将其下载到本地,进而进行二次利用与传播。换言之,私有读写权限以及防盗链功能,保障的是文件访问链路的安全性,但没有对文件内容本身做处理,一旦文件被下载到本地,便可以肆意妄为。
那么该如何保障源文件内容本身的安全性?接下来就隆重有请本期 COS 音视频实践的主角——视频加密功能。
视频加密是对视频文件进行加密处理,可以确保即使您的视频被下载到本地,但由于视频本身是加密过的,是“上了锁”的,所以是安全的,其他人无法进行二次利用。
二. 实现原理和步骤说明
本文使用的加密方式是 COS HLS 转码加密,对转码生成的视频分片进行加密处理。HLS(全称是HTTP Live Streaming)是一个由苹果公司提出的基于 HTTP 的流媒体网络传输协议,它是苹果公司 QuickTime X 和 iPhone 软件系统的一部分。它的工作原理是把整个流分成一个个小的基于 HTTP 的文件分片来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的 extended M3U m3u8playlist 文件,用于寻找可用的媒体流。
2.1 实现原理
1)流程图:
2)加密流程:
1、用户侧将视频文件上传到 COS,触发 COS 数据工作流。
2、COS 收到加密请求后,向 KMS 服务请求加密密钥。
3、COS 拿到加密密钥后,对视频文件进行 HLS 转码加密。
4、加密完成后,COS 通过 CDN 分发加密后的 HLS 视频文件。
3)解密流程:
1、获取加密生成的 m3u8 文件对象地址。
2、播放器解析 m3u8 文件,向密钥服务请求解密密钥。
3、密钥服务先根据用户逻辑自行判断用户身份合法性,再通过调用 KMS 服务的 API 查询密钥,返回给播放器。
4、播放器拿到解密密钥后,对 HLS 视频分片进行解密并播放。
说明:
- KMS 服务:本加密方案中,COS 接入了腾讯云 KMS 服务。腾讯云 KMS 服务是一款安全管理类服务,可以轻松创建和管理密钥,保护密钥的保密性、完整性和可用性。
- 密钥服务:业务侧需自行搭建的密钥服务,用户身份鉴权和解密密钥的获取。
2.2 整体步骤
基于上述原理,进行如下三个详细操作步骤,便可以实现对视频的加解密与播放。文末我们提供了一个样例 demo,欢迎体验。
- 控制台配置步骤;
- 搭建密钥服务;
- 播放 HLS 加密视频;
三. 详细步骤
3.1 COS 控制台配置步骤
COS 数据工作流,帮助您快速、灵活、按需搭建视频处理流程。每个工作流与输入存储桶的一个路径绑定,当视频文件上传至该路径时,该媒体工作流就会被自动触发,执行指定的处理操作,并将处理结果自动保存至输出存储桶的指定路径下。此外,若针对已存在于存储桶中的文件,您可创建任务进行媒体处理、语音识别、文档处理等操作,快速帮您完成单任务处理。
1、登录 对象存储控制台) 进入存储桶管理页面并找到视频存储桶;
2、在左侧导航栏中,选择数据工作流 > 公共配置 > 模板,进入模板配置页面。
3、选择音视频转码,单击创建转码模板,配置如下信息:
4、单击确定,完成加密模板配置后,在左侧导航栏中,选择数据工作流 > 工作流 > 创建工作流,进行工作流配置。
5、添加音视频转码任务节点,选择刚刚创建的自定义模版,配置如下:
7、上传视频文件,便能看到生成了对应的加密 HLS 视频文件。其中 ts 文件是加密过后的视频分片,m3u8 文件作为索引文件,文件内容包含 ts 分片地址以及密钥服务地址。
3.2 搭建密钥服务
密钥服务用于业务侧身份鉴权和解密密钥的获取,先根据用户逻辑自行判断用户身份合法性,身份验证通过后,再通过调用 KMS 服务的 API 查询密钥,返回给播放器。
1、进入 密钥相关接口,根据自己的开发语言生成对应的 KMS API 调用示例代码。
2、下面以 Node.js 为例,基于 KMS API 调用示例代码,搭建一个 HTTP Server 作为密钥服务,获取解密密钥。
const Koa = require('koa')
const cors = require('koa2-cors')
const app = new Koa()
const tencentcloud = require("tencentcloud-sdk-nodejs")
app.use(cors()) // 跨域配置
app.use(getKMSDecryptKey(ctx)) // 获取 KMS 解密密钥
// 监听8080端口
app.listen('8080', () => {
console.log('127.0.0.1:8080');
})
// 获取 KMS 解密密钥中间件
async function getKMSDecryptKey(ctx) {
// 生成的m3u8文件中的URI请求会默认带上参数
const { Ciphertext, KMSRegion } = ctx.query
const KmsClient = tencentcloud.kms.v20190118.Client
const clientConfig = {
credential: {
// 账号API密钥,可前往https://console.cloud.tencent.com/cam/capi获取
secretId: "SecretId",
secretKey: "SecretKey",
},
region: KMSRegion, // 所在园区,eg:"ap-guangzhou"
profile: {
httpProfile: {
endpoint: "kms.tencentcloudapi.com",
},
},
};
// 创建KMS对象实例
const client = new KmsClient(clientConfig);
const params = {
"CiphertextBlob": Ciphertext,
};
try {
// 发起请求,获取解密密钥
const res = await client.Decrypt(params)
// 取出密钥,base64解密后返回其二进制数据
const plaintext = res.Plaintext
const plainBuff = Buffer.from(plaintext, 'base64');
ctx.body = plainBuff
} catch (error) {
console.log(error);
}
}
3.3 播放 HLS 加密视频
利用腾讯云超级播放器,传入 HLS 加密生成的 m3u8 文件对象地址,播放器解析 m3u8 文件,向密钥服务地址 UriKey 获取密钥后,解密对应的视频分片,进而播放视频。
1、在页面中引入播放器样式文件与脚本文件;
建议在正式使用播放器SDK时,自行部署以上相关静态资源,单击下载播放器资源。
部署解压后的文件夹,不能调整文件夹里面的目录,避免资源互相引用异常。
2、设置播放器容器节点;
在需要展示播放器的页面位置加入播放器容器。例如,在 index.html 中加入如下代码(容器 ID 以及宽高都可以自定义)。
3、初始化播放器并设置 URL;
1)获取前面控制台配置步骤中加密生成的 m3u8 文件对象地址;
2)初始化播放器,并传入 m3u8 对象地址。
var player = TCPlayer('player-container-id', {}); // player-container-id 为播放器容器 ID,必须与 html 中一致
player.src(https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/path/example.m3u8); // m3u8对象地址
3.4 效果
1、成功获取到 m3u8 文件和解密密钥;
2、成功解密并播放视频;
3、若直接下载 ts 视频分片到本地,由于视频本身是加密过的,因此无法播放,保障视频的安全性。
四. 体验
以上实践,我们准备了一个线上体验demo,欢迎大家体验~
1、移动端:扫码即可进行体验;
2、web 端:点击链接即可进行体验;
展望
本期「COS 音视频实践」到此结束,欢迎大家体验使用,下期精彩内容,敬请期待。