先说下原理:因为视频是付费的,肯定需要作视频加密处理。

加密可实现的方式:修改视频字节流,只能替换字节流,例如头100-1024字节进行加密,源文件就无法打开了。

下面上代码吧,加解密是

  1. openssl_encrypt
  1. openssl_decrypt
  1. <?php
  2. /**
  3. *
  4. * Created by PhpStorm.
  5. * User: js
  6. * Date: 2021/04/15
  7. * Time: 17:03
  8. * PhpStorm
  9. */
  10.  
  11. namespace CoreModel\Payfilms;
  12.  
  13. class Movie{
  14. const KEY = 'jiangsheng';
  15. const METHOD = 'des-ecb';
  16.  
  17. static function movieModify($filename){
  18. $strLong = mt_rand(1,9);
  19. $str = self::randStr($strLong); // 字符串占位
  20. $key = self::randStr(6); // key
  21. $Pkey = base64_encode($key);
  22. $fp = fopen($filename, 'r+') or die('文件打开失败!');
  23. $bin = fread($fp, $strLong); //随机
  24. $passStr = self::_encrypt($bin,$key); // 密文头 转存
  25.  
  26. // 判断是否是小写字母组成
  27.  
  28. $i = 0;
  29. while (!feof($fp)) {
  30. //修改第二行数据
  31. if ($i == 0) {
  32. fseek($fp, 0);// 移动文件指针至偏移量处
  33. fwrite($fp, $str);
  34. break;
  35. }
  36. fgets($fp);
  37. $i++;
  38. }
  39. fclose($fp);
  40. return [
  41. 'key'=>$key,
  42. 'Pkey'=>$Pkey,
  43. 'passStr'=>$passStr,
  44. 'str'=>$str,
  45. 'bin'=>$bin
  46. ];
  47. }
  48.  
  49. static function movieReduction($filename, $passStr, $Pkey){
  50. $fp = fopen($filename, 'r+') or die('文件打开失败!');
  51. $key = base64_decode($Pkey);
  52. $str = self::_decrypt($passStr,$key);
  53. $i = 0;
  54. while (!feof($fp)) {
  55. //修改第二行数据
  56. if ($i == 0) {
  57. fseek($fp, 0);// 移动文件指针至偏移量处
  58. fwrite($fp,$str);
  59. break;
  60. }
  61. fgets($fp);
  62. $i++;
  63. }
  64. fclose($fp);
  65. return true;
  66. }
  67. static function handOpen($filename){
  68. $fp = fopen($filename, 'r') or die('文件打开失败!');
  69. $content = fread($fp, filesize($filename));
  70. return $content;
  71. }
  72.  
  73. static function _encrypt($data, $key=self::KEY, $method=self::METHOD){
  74. return openssl_encrypt($data, $method, $key);
  75. }
  76.  
  77. static function _decrypt($data, $key=self::KEY, $method=self::METHOD){
  78. return openssl_decrypt($data, $method, $key);
  79. }
  80.  
  81. static function authcode($string,$key='',$operation=false,$expiry=0){
  82. $ckey_length = 4;
  83. $key = md5($key ? $key : self::KEY);
  84. $keya = md5(substr($key, 0, 16));
  85. $keyb = md5(substr($key, 16, 16));
  86. $keyc = $ckey_length ? ($operation? substr($string, 0, $ckey_length):substr(md5(microtime()), -$ckey_length)) : '';
  87. $cryptkey = $keya.md5($keya.$keyc);
  88. $key_length = strlen($cryptkey);
  89. $string = $operation? base64_decode(substr($string, $ckey_length)) :
  90. sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
  91. $string_length = strlen($string);
  92. $result = '';
  93. $box = range(0, 255);
  94. $rndkey = array();
  95. for($i = 0; $i <= 255; $i++) {
  96. $rndkey[$i] = ord($cryptkey[$i % $key_length]);
  97. }
  98. for($j = $i = 0; $i < 256; $i++) {
  99. $j = ($j + $box[$i] + $rndkey[$i]) % 256;
  100. $tmp = $box[$i];
  101. $box[$i] = $box[$j];
  102. $box[$j] = $tmp;
  103. }
  104. for($a = $j = $i = 0; $i < $string_length; $i++) {
  105. $a = ($a + 1) % 256;
  106. $j = ($j + $box[$a]) % 256;
  107. $tmp = $box[$a];
  108. $box[$a] = $box[$j];
  109. $box[$j] = $tmp;
  110. $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
  111. }
  112. if($operation) {
  113. if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&
  114. substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
  115. return substr($result, 26);
  116. } else {
  117. return '';
  118. }
  119. } else {
  120. return $keyc.str_replace('=', '', base64_encode($result));
  121. }
  122. }
  123.  
  124. static function randStr($randLength = 6, $addtime = 0, $includenumber = 0)
  125. {
  126. if ($includenumber) {
  127. $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789';
  128. } else {
  129. $chars = 'abcdefghijklmnopqrstuvwxyz';
  130. }
  131. $len = strlen($chars);
  132. $randStr = '';
  133. for ($i = 0; $i < $randLength; $i++) {
  134. $randStr .= $chars[mt_rand(0, $len - 1)];
  135. }
  136. $tokenvalue = $randStr;
  137. if ($addtime) {
  138. $tokenvalue = $randStr . time();
  139. }
  140. return $tokenvalue;
  141. }
  142. }

  1. // 批量加密
  2. function index(){
  3. ini_set('max_execution_time', 0);//秒为单位,自己根据需要定义
  4. set_time_limit(0);
  5. // $code = $this->arguments['code'];
  6. // $sta = $this->arguments['sta'];
  7. // $end = $this->arguments['end'];
  8. // var_dump($code,$sta,$end);
  9. // echo $res = Movies::_encrypt('123');
  10. // echo $res = Movies::_decrypt($res);
  11.  
  12. $moviePath = FCPATH.'movie'.DIRECTORY_SEPARATOR; // 视频目录
  13. $data = [
  14. ['ID'=>1,'VideoFile'=>'huzongdieying.zip'],
  15. ['ID'=>2,'VideoFile'=>'27000084-bstg.mp4']
  16. ];
  17.  
  18. $obj = new FilmFiles();
  19. foreach($data as $key=>$val){
  20. $filePath = $moviePath.$val['VideoFile'];
  21.  
  22. $res = Movies::movieModify($filePath);
  23. if($res){
  24. $where = ['ID'=>$val['ID']];
  25. $info = [
  26. 'EncryptType'=>3,
  27. 'SecretKey'=>$res['Pkey'],
  28. 'SecretEncrypt'=>$res['passStr']
  29. ];
  30. $sta = $obj->updateLine($where,$info);
  31. var_dump($res,$sta);
  32. }
  33. }
  34. }
  35. // 批量解密
  36. function indexOut(){
  37. ini_set('max_execution_time', 0);//秒为单位,自己根据需要定义
  38. set_time_limit(0);
  39. $moviePath = FCPATH.'movie'.DIRECTORY_SEPARATOR;
  40. $data = [
  41. ['ID'=>1,'VideoFile'=>'a.mkv'],
  42. ['ID'=>2,'VideoFile'=>'b.mkv']
  43. ];
  44.  
  45. $obj = new FilmFiles();
  46. $where = ['ID'=>1,'ID'=>2];
  47. $data = $obj->getList();
  48.  
  49. foreach($data as $val){
  50. $filePath = $moviePath.$val->VideoFile;
  51.  
  52. $res = Movies::movieReduction($filePath, $val->SecretEncrypt, $val->SecretKey);
  53. if($res){
  54. $where = ['ID'=>$val->ID];
  55. $info = [
  56. 'EncryptType'=>0,
  57. 'SecretKey'=>'',
  58. 'SecretEncrypt'=>''
  59. ];
  60. $sta = $obj->updateLine($where,$info);
  61. var_dump($res,$sta);
  62. }
  63.  
  64. }
  65. }

以下是数据库类,可以参考

  1. <?php
  2. /*
  3. * js
  4. * Time 14:26
  5. * File FilmFiles.php
  6. * 数据库Model处理数据更改
  7. */
  8.  
  9. namespace CoreModel\Payfilms;
  10.  
  11. use Config\Database;
  12.  
  13. class FilmFiles
  14. {
  15. //Model Path: CoreModel/Payfilms
  16. protected $db;
  17. protected $bld;
  18. public $Total = 0;
  19.  
  20. public function __construct()
  21. {
  22. $connect = Database::connect();
  23. $this->db = &$connect;
  24. $this->bld = $this->db->table($this->Table);
  25. }
  26.  
  27. private $Table = "payfilm_file";
  28. public $SelectFields = "ID,`DoubanID` ,`VideoFile` ,`VideoSize` ,`VideoMD5` ,`TorrentFile` ,`TorrentMD5` ,`FrameType` ,`Ratio` ,`Bitrate` ,`Format` ,`Acoustics` ,`SoundChannel` ,`EncryptType` ,`SecretKey` ,`SecretEncrypt`";
  29.  
  30. function getCount($where = [])
  31. {
  32. $this->bld->select("count(ID) as Total");
  33. if (isset($where["limit"])) {
  34. unset($where["limit"]);
  35. }
  36. $this->where($where);
  37. $res = $this->bld->get()->getResultArray();
  38. log_message("debug", "CoreModel/Payfilms/FilmFiles ->getCount \nSQL: " . $this->db->getLastQuery());
  39. return $res[0]["Total"];
  40. }
  41.  
  42. function where($where)
  43. {
  44. foreach ($where as $k => $v) {
  45. switch ($k) {
  46. case "ID":
  47. $this->bld->where("ID", $v);
  48. break;
  49. case "DoubanID":
  50. $this->bld->where("DoubanID", $v);
  51. break;
  52. case "VideoFile":
  53. $this->bld->where("VideoFile", $v);
  54. break;
  55. case "VideoSize":
  56. $this->bld->where("VideoSize", $v);
  57. break;
  58. case "VideoMD5":
  59. $this->bld->where("VideoMD5", $v);
  60. break;
  61. case "TorrentFile":
  62. $this->bld->where("TorrentFile", $v);
  63. break;
  64. case "TorrentMD5":
  65. $this->bld->where("TorrentMD5", $v);
  66. break;
  67. case "FrameType":
  68. $this->bld->where("FrameType", $v);
  69. break;
  70. case "Ratio":
  71. $this->bld->where("Ratio", $v);
  72. break;
  73. case "Bitrate":
  74. $this->bld->where("Bitrate", $v);
  75. break;
  76. case "Format":
  77. $this->bld->where("Format", $v);
  78. break;
  79. case "Acoustics":
  80. $this->bld->where("Acoustics", $v);
  81. break;
  82. case "SoundChannel":
  83. $this->bld->where("SoundChannel", $v);
  84. break;
  85. case "EncryptType":
  86. $this->bld->where("EncryptType", $v);
  87. break;
  88. case "SecretKey":
  89. $this->bld->where("SecretKey", $v);
  90. break;
  91. case "SecretEncrypt":
  92. $this->bld->where("SecretEncrypt", $v);
  93. break;
  94. case "operator":
  95. foreach ($v as $a => $b) {
  96. if (array_key_exists(0, $b)) {
  97. $this->bld->where($a . $b[0], $b[1]);
  98. continue;
  99. }
  100. foreach ($b as $n => $m) {
  101. $this->bld->where($a . $n, $m);
  102. }
  103. }
  104. break;
  105. case "between":
  106. foreach ($v as $a => $b) {
  107. $this->bld->where($a . ">=", $b[0]);
  108. $this->bld->where($a . "<=", $b[1]);
  109. }
  110. break;
  111. case "order_by":
  112. foreach ($v as $a => $b) {
  113. $this->bld->orderBy($a, $b);
  114. }
  115. break;
  116. case "not_in":
  117. foreach ($v as $a => $b) {
  118. $this->bld->whereNotIn($a, $b);
  119. }
  120. break;
  121. case "like":
  122. foreach ($v as $a => $b) {
  123. $this->bld->like($a, $b);
  124. }
  125. case "limit":
  126. $this->bld->limit($v, isset($where["offset"]) ? $where["offset"] : 0);
  127. break;
  128. }
  129. }
  130. }
  131.  
  132. function getList($where = [])
  133. {
  134. $this->bld->select($this->SelectFields);
  135. $this->where($where);
  136. $this->Total = $this->bld->countAllResults(false);
  137. $res = $this->bld->get()->getResult();
  138. log_message("debug", "CoreModel/Payfilms/FilmFiles->getList \nSQL: " . $this->db->getLastQuery());
  139. if (count($res) > 0) {
  140. return $res;
  141. }
  142. return false;
  143. }
  144.  
  145. function updateLine($where, $info)
  146. {
  147.  
  148. $this->where($where);
  149. $data = [];
  150. foreach ($info as $k => $v) {
  151. switch ($k) {
  152. case "DoubanID":
  153. $data["DoubanID"] = $v;
  154. break;
  155. case "VideoFile":
  156. $data["VideoFile"] = $v;
  157. break;
  158. case "VideoSize":
  159. $data["VideoSize"] = $v;
  160. break;
  161. case "VideoMD5":
  162. $data["VideoMD5"] = $v;
  163. break;
  164. case "TorrentFile":
  165. $data["TorrentFile"] = $v;
  166. break;
  167. case "TorrentMD5":
  168. $data["TorrentMD5"] = $v;
  169. break;
  170. case "FrameType":
  171. $data["FrameType"] = $v;
  172. break;
  173. case "Ratio":
  174. $data["Ratio"] = $v;
  175. break;
  176. case "Bitrate":
  177. $data["Bitrate"] = $v;
  178. break;
  179. case "Format":
  180. $data["Format"] = $v;
  181. break;
  182. case "Acoustics":
  183. $data["Acoustics"] = $v;
  184. break;
  185. case "SoundChannel":
  186. $data["SoundChannel"] = $v;
  187. break;
  188. case "EncryptType":
  189. $data["EncryptType"] = $v;
  190. break;
  191. case "SecretKey":
  192. $data["SecretKey"] = $v;
  193. break;
  194. case "SecretEncrypt":
  195. $data["SecretEncrypt"] = $v;
  196. break;
  197. }
  198. }
  199. $this->bld->update($data);
  200. log_message("debug", "CoreModel/Payfilms/FilmFiles->updateLine \nSQL: " . $this->db->getLastQuery());
  201. if ($this->db->affectedRows() > 0) {
  202. return true;
  203. }
  204. return false;
  205. }
  206.  
  207. function deleteLine($where)
  208. {
  209. $this->where($where);
  210. $this->bld->delete();
  211. log_message("debug", "CoreModel/Payfilms/FilmFiles->deleteLine \nSQL: " . $this->db->getLastQuery());
  212. if ($this->db->affectedRows() > 0) {
  213. return true;
  214. }
  215. return false;
  216. }
  217.  
  218. function insertLine($info)
  219. {
  220. $data = [
  221. "DoubanID" => $info["DoubanID"],
  222. "VideoFile" => $info["VideoFile"],
  223. "VideoSize" => $info["VideoSize"],
  224. "VideoMD5" => $info["VideoMD5"],
  225. "TorrentFile" => $info["TorrentFile"],
  226. "TorrentMD5" => $info["TorrentMD5"],
  227. "FrameType" => $info["FrameType"],
  228. "Ratio" => $info["Ratio"],
  229. "Bitrate" => $info["Bitrate"],
  230. "Format" => $info["Format"],
  231. "Acoustics" => $info["Acoustics"],
  232. "SoundChannel" => $info["SoundChannel"],
  233. "EncryptType" => $info["EncryptType"],
  234. "SecretKey" => $info["SecretKey"],
  235. "SecretEncrypt" => $info["SecretEncrypt"],
  236. ];
  237. $this->bld->insert($data);
  238. log_message("debug", "CoreModel/Payfilms/FilmFiles->insertLine \nSQL: " . $this->db->getLastQuery());
  239. if ($this->db->affectedRows() > 0) {
  240. return $this->db->insertID();
  241. }
  242.  
  243. return false;
  244. }
  245.  
  246. function updateByID($ID, $info)
  247. {
  248. return $this->updateLine(["ID" => $ID], $info);
  249. }
  250.  
  251. function getItemByID($ID)
  252. {
  253. $res = $this->getList(["ID" => $ID]);
  254. if (is_array($res)) {
  255. return $res[0];
  256. }
  257. return false;
  258. }
  259.  
  260. function deleteByID($DoubanID)
  261. {
  262. return $this->deleteLine(["DoubanID" => $DoubanID]);
  263. }
  264.  
  265. function getListByDouban($DoubanID, $Ext = [])
  266. {
  267. $where = ["DoubanID" => $DoubanID];
  268. $where = array_merge($where, $Ext);
  269. $res = $this->getList($where);
  270. if (is_array($res)) {
  271. return $res;
  272. }
  273. return false;
  274. }
  275.  
  276. function deleteByDouban($DoubanID)
  277. {
  278. return $this->deleteLine(["DoubanID" => $DoubanID]);
  279. }
  280. }

PHP 视频源文件加密方案的更多相关文章

  1. lua 代码加密方案

    require 实现 require函数在实现上是依次调用package.searchers(lua51中是package.loaders)中的载入函数,成功后返回.在loadlib.c文件里有四个载 ...

  2. 如何保护你的 Python 代码 (一)—— 现有加密方案

    https://zhuanlan.zhihu.com/p/54296517 0 前言 去年11月在PyCon China 2018 杭州站分享了 Python 源码加密,讲述了如何通过修改 Pytho ...

  3. Atitit.视频文件加密的方法大的总结 java c# php

    Atitit.视频文件加密的方法大的总结 java c# php 1. 加密的算法  aes  3des  des xor等.1 2. 性能1 3. 解密1 4. 播放器的事件扩展1 5. 自定义格式 ...

  4. 一个异或加密方案--C语言实现

    核心代码: char encrypt( char f , char c) { return f^c; } int OutEncrypt( char *FilePath, char *SecretWor ...

  5. C# .net 语言加密方案

    C# .net 语言加密方案 方案背景 当前C# .net语言的应用范围越来越广泛,IIS 的服务器架构后台代码.桌面应用程序的 winform .Unity3d 的逻辑脚本都在使用.C# .net ...

  6. 基于HTTP在互联网传输敏感数据的消息摘要、签名与加密方案

    基于HTTP在互联网传输敏感数据的消息摘要.签名与加密方案 博客分类: 信息安全 Java 签名加密AESMD5HTTPS  一.关键词 HTTP,HTTPS,AES,SHA-1,MD5,消息摘要,数 ...

  7. 网络摄像机进行互联网视频直播录像方案的选择,EasyNVS or EasyCloud or EasyGBS?

    背景需求 互联网视频直播越来越成为当前大势:直播的需求往往都伴随在录像的需求,对于录像,不同的场景又有不同的方案选择: 本篇博客将会介绍对应的几种录像方案,可以帮助有互联网录像需求的用户进行对应的录像 ...

  8. [原创]aaencode等类似js加密方案破解方法

    受http://tieba.baidu.com/p/4104806767 2L启发,不过他说的方法,我没有尝试成功,自己摸索出了一个新方法,在这里分享下. 首先拿aaencode官网的加密字符串作为例 ...

  9. nginx视频服务缓存方案设置指导

    本文描述了如何通过设置nginx缓存达到降低服务器后端压力的效果以及结合nginx第三方插件ngx_cache_purge实现nginx缓存后的自动清理功能.具体实施步骤如下所示:第一步:获取清除清除 ...

  10. 基于RSA的WEB前端密码加密方案

    受制于WEB页面源码的暴露,因此传统的对称加密方案以及加密密钥都将暴露在JS文件中,同样可以被解密. 目前比较好的解决方案是WEB页面全程或用户登录等关键环节使用HTTPS进行传输. 另外一种解决方案 ...

随机推荐

  1. Portainer 安装MySQL并开启远程访问

    进入到 Portainer 页面,选择左边的 Containers 选项,单击上方的 Add container 按钮转到如图所示的页面: 1.在 Name 一栏中输入容器名字: 2.在 Image ...

  2. ELK 性能优化实践 ---总结篇

    版本及硬件配置 JDK:JDK1.8_171-b11 (64 位) ES集群:由3台16核32G的虚拟机部署 ES 集群,每个节点分配 20 G 堆内存 ELK版本:6.3.0 垃圾回收器:ES 默认 ...

  3. 十分钟速成DevOps实践

    摘要:以华为云软件开发平台DevCloud为例,十分钟简单体验下DevOps应用上云实践--H5经典小游戏上云. 本文分享自华为云社区<<DevOps实践秘籍>十分钟速成DevOps ...

  4. Springboot 之 Mybatis-plus 多数据源

    简介 Mybatis-puls 多数据源的使用,采用的是官方提供的dynamic-datasource-spring-boot-starter包的 @DS 注解,具体可以参考官网: https://g ...

  5. CentOS 7.9 安装 kafka_2.13

    一.CentOS 7.9 安装 kafka_2.13 地址 https://kafka.apache.org/downloads.html 二.安装准备 1 安装JDK 在安装kafka之前必须先安装 ...

  6. 2022年实时最新省市区县乡镇街道geojson行政边界数据获取方法

    geojson 数据下载地址:https://hxkj.vip/demo/echartsMap/ 可下载的数据包含省级geojson行政边界数据.市级geojson行政边界数据.区/县级geojson ...

  7. 前端框架Vue------>第一天学习(3)

    文章目录 8 .使用Axios实现异步通信 9 .表单输入绑定 9.1 . 什么是双向数据绑定 9.2 .为什么要实现数据的双向绑定 9.3 .在表单中使用双向数据绑定 8 .使用Axios实现异步通 ...

  8. 如何在IDEA中创建Module、以及怎样在IDEA中删除Module?

    文章目录 1.为何要使用Module? 2.Module的创建 3.如何从硬盘上删除module 1.为何要使用Module? 目前主流的大型项目都是分布式部署的,结构类型这种多Module结构.不同 ...

  9. JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题

    1.线程和进程 进程:一个程序,微信.qq...程序的集合.(一个进程包含多个线程,至少包含一个线程.java默认有两个线程:主线程(main).垃圾回收线程(GC) 线程:runnable.thre ...

  10. python dir函数解析

    dir() 函数  不带参数,直接执行是返回当前环境中对象的名称列表.指定对象的名称作为参数执行,返回指定对象当中的属性(包括函数名,类名,变量名等)   下面我们具体找几个例子测试一下  dir() ...