当前位置:首页 > 技术分析 > 正文内容

离线资源的加密保护

ruisui883周前 (04-07)技术分析19

上次提到过工作中有个阅读器项目要做成离线版,其中涉及到离线资源的加密保护,需求如下:

1)产品为U盘形式,里面包含阅读器程序和课本资源两部分;

2)课本资源包括视频、音频、HTML5等格式,为了防止用户拷贝传播这些数据,考虑对它们资源进行加密以增加安全性;

3)课本资源整体是HTML5形式,首页是一个书本目录,下面包含很多单元,点击某个单元会跳转到对应的页面;

4)课本资源总体积好几G,每个单元约200多M,要支持远程对单个单元数据进行更新。

下文是为此设计的一个资源加密的粗简方案(毕竟不存在绝对的安全,所以这里并不追求加密的复杂性,仅仅只做个最基础的保护)。

环境:Windows

框架:Electron

语言:JS

资源加密,其实就是对正常文件进行破坏,只要用的时候有办法恢复就行。恢复的时候,避免将临时数据放到本地磁盘,以免被用户拷贝。

根据文件类型的不同,加密的方式和难度也不同。

一、视频音频

视频音频,破坏起来比较容易,可以用AES,或者对局部Buffer数据进行异或运算(参考微信DAT文件加密方式),往往稍微修改一点就可以导致其无法正常播放。

当阅读器播放音频视频的时候,首先读取到文件的Buffer数据(加密),然后对其进行解密得到新的Buffer数据,最后将其转换成blob地址并交给video标签或audio标签播放即可。

核心代码如下:

// 读取资源+解密+转换为URL
function res2url ({fileName, mimeType}) {
  if (!fileName) return Promise.resolve()
  if (fileName.includes('/')) {
    fileName = fileName.split('/').pop()
  }
  let filePath = path.join(resDir, fileName) // resDir资源目录,fileName文件名
  return new Promise((resolve, reject) => {
    fs.readFile(filePath, (err, data) => {
      if (err) {
        reject(err)
      } else {
        data = decrypt(data) // 解密
        let bufferData = new Uint8Array(data)
        let blobData = new Blob([bufferData], { type: mimeType })
        resolve(URL.createObjectURL(blobData))
      }
    })
  })
}

二、HTML5

H5资源,因为文件数量众多,单个加密解密耗时耗力,再结合资源目录结构,以及单元更新的需求,考虑设计方案如下:

1)将目录文件夹和单元文件夹分别打包成ZIP,再对每个ZIP包进行加密(加密方式不能只修改局部Buffer,这样只会对部分文件造成损坏);

2)当要更新单元数据时,替换掉相应的单元ZIP加密包即可;

3)当阅读器要使用H5时,首先用express启动一个WEB服务器,同时将课本目录ZIP解密并用Jszip装载,然后在阅读器中用iframe加载WEB服务器首页(比如访问index.html),服务器监听到请求后,从jszip对象中取出对应的文件返回即可;

4)当要访问某个单元时,根据地址可以判断出需要从哪个ZIP包中获取,然后读取该ZIP包并解密、用Jszip装载,然后将数据返回。

Demo示例如下:

Demo核心代码:

// 读取资源 + 解密 => jszip对象
loadZipItem (zipName) {
  let zipPath = this.zipPathDict[zipName] // ZIP文件路径
  let zipData = fs.readFileSync(zipPath) // ZIP文件数据
  zipData = this.decrypt(zipData) // 解密ZIP文件数据
  return JSZip.loadAsync(zipData).then((zip) => {
    zipDataDict[zipName] = zip // 保存jszip对象,方便后续调用
  })
},
// 根据请求地址path获取对应的jszip对象
async getZipData (_path) {
  let _arr = _path.split('/')
  // 默认返回入口ZIP文件
  if (_arr.length === 1 || !this.zipPathDict[_arr[0]]) { return zipDataDict['main'] }
  // 读取子ZIP文件,如果不存在则加载
  if (!zipDataDict[_arr[0]]) {
    await this.loadZipItem(_arr[0])
  }
  // 返回计算后的ZIP文件
  return zipDataDict[_arr[0]]
},
// 启动WEB服务
async serverStart () {
  let app = express()
  await this.loadZipItem('main') // 加载入口ZIP文件
  app.get('/:path(*)', async (req, res) => {
    let _path = req.params.path
    if (this.zipChildPathPrefix && _path.indexOf(this.zipChildPathPrefix) === 0) {
      _path = _path.substring(this.zipChildPathPrefix.length)
    }
    let _zip = await this.getZipData(_path)
    let _file = _zip.file(_path)
    let _fileName = path.basename(_path)
    if (_file) {
      _file.async('nodebuffer').then((content) => {
        res.type(_fileName)
        res.send(content)
      }).catch((err) => {
        res.status(500).send('读取文件内容时出错')
      })
    } else {
      res.status(404).send('文件未找到')
    }
  })
  app.listen(this.port, () => {
    this.result += `服务器运行在 http://localhost:${this.port}` + '\n'
  })
}

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/3325.html

标签: readfilesync
分享给朋友:

“离线资源的加密保护” 的相关文章

费用管理解决企业财务难题

目前来讲,国内大多数企业费用预算管理都是由财务部门“一手包办”,与之相适应的是费用管理的信息化手段是通过财务管理软件来实现,仅仅局限于财务预算管理层面,从而使预算管理处于“预而不算”的状态,表现为信息滞后、执行者在执行预算过程中处于被动地位、可控性差、考核难以奏效。而且由于对各部门预算缺乏约束力,员...

Excel VBA 收费单据打印/一步一步带你设计【收费管理系统】12

本文于2023年6月10日首发于本人同名公众号:Excel活学活用,更多文章案例请搜索关注!☆本期内容概要☆用户窗体设置:收费结算模块设置(7)单据打印大家好,我是冷水泡茶,前几期我们分享了【收费管理系统】的设计,最近一期是(Excel VBA 收费结算模块/一步一步带你设计【收费管理系统】11),...

BuildKit 镜像构建工具

#暑期创作大赛#快速开始 对于 Kubernetes 部署,请参阅examples/kubernetes。BuildKit 由buildkitd守护进程和buildctl客户端组成。虽然buildctl客户端可用于 Linux、macOS 和 Windows,但buildkitd守护程序目前仅适用于...

Acustica Audio 发布模拟Roland Jupiter 双声道合成器插件 TH2

福利: Acustica Audio 发布模拟Roland Jupiter 风格的双声道合成器插件 TH2 免费下载 意大利 Acustica Audio 公司发布布模拟Roland Jupiter 风格的双声道合成器插件 TH2 ,灵感来源于Acustica Audio的THING-8系列,它是...

你感动了吗?佳能超规格镜头 RF 24-105mm F2.8深度测评

如果要你选一支用作多题材创作的挂机镜头,那我相信很多人会选择24-105mm这个焦段的镜头。作为一支可以实现从广角到长焦的变焦镜头,24-105mm有着丰富的焦段选择。只是基于镜头体积以及光学结构上的限制,此前的24-105mm镜头只能恒定在F4的光圈。而佳能打破了这一限制,将实用焦段和恒定光圈完美...

三勾商城(java+vue3)微信小程序商城+SAAS+前后端源码

项目介绍本系统功能包括: 前台展示+后台管理+SAAS管理端,包括最基本的用户登录注册,下单, 购物车,购买,结算,订单查询,收货地址,后台商品管 理,订单管理,用户管理等等功能,小伙伴一起来看看吧。三勾小程序商城基于springboot+element-ui+uniapp打造的面向开发的小程序商城...