PHP 视频源文件加密方案
先说下原理:因为视频是付费的,肯定需要作视频加密处理。
加密可实现的方式:修改视频字节流,只能替换字节流,例如头100-1024字节进行加密,源文件就无法打开了。
下面上代码吧,加解密是
- openssl_encrypt
- openssl_decrypt
- <?php
- /**
- *
- * Created by PhpStorm.
- * User: js
- * Date: 2021/04/15
- * Time: 17:03
- * PhpStorm
- */
- namespace CoreModel\Payfilms;
- class Movie{
- const KEY = 'jiangsheng';
- const METHOD = 'des-ecb';
- static function movieModify($filename){
- $strLong = mt_rand(1,9);
- $str = self::randStr($strLong); // 字符串占位
- $key = self::randStr(6); // key
- $Pkey = base64_encode($key);
- $fp = fopen($filename, 'r+') or die('文件打开失败!');
- $bin = fread($fp, $strLong); //随机
- $passStr = self::_encrypt($bin,$key); // 密文头 转存
- // 判断是否是小写字母组成
- $i = 0;
- while (!feof($fp)) {
- //修改第二行数据
- if ($i == 0) {
- fseek($fp, 0);// 移动文件指针至偏移量处
- fwrite($fp, $str);
- break;
- }
- fgets($fp);
- $i++;
- }
- fclose($fp);
- return [
- 'key'=>$key,
- 'Pkey'=>$Pkey,
- 'passStr'=>$passStr,
- 'str'=>$str,
- 'bin'=>$bin
- ];
- }
- static function movieReduction($filename, $passStr, $Pkey){
- $fp = fopen($filename, 'r+') or die('文件打开失败!');
- $key = base64_decode($Pkey);
- $str = self::_decrypt($passStr,$key);
- $i = 0;
- while (!feof($fp)) {
- //修改第二行数据
- if ($i == 0) {
- fseek($fp, 0);// 移动文件指针至偏移量处
- fwrite($fp,$str);
- break;
- }
- fgets($fp);
- $i++;
- }
- fclose($fp);
- return true;
- }
- static function handOpen($filename){
- $fp = fopen($filename, 'r') or die('文件打开失败!');
- $content = fread($fp, filesize($filename));
- return $content;
- }
- static function _encrypt($data, $key=self::KEY, $method=self::METHOD){
- return openssl_encrypt($data, $method, $key);
- }
- static function _decrypt($data, $key=self::KEY, $method=self::METHOD){
- return openssl_decrypt($data, $method, $key);
- }
- static function authcode($string,$key='',$operation=false,$expiry=0){
- $ckey_length = 4;
- $key = md5($key ? $key : self::KEY);
- $keya = md5(substr($key, 0, 16));
- $keyb = md5(substr($key, 16, 16));
- $keyc = $ckey_length ? ($operation? substr($string, 0, $ckey_length):substr(md5(microtime()), -$ckey_length)) : '';
- $cryptkey = $keya.md5($keya.$keyc);
- $key_length = strlen($cryptkey);
- $string = $operation? base64_decode(substr($string, $ckey_length)) :
- sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
- $string_length = strlen($string);
- $result = '';
- $box = range(0, 255);
- $rndkey = array();
- for($i = 0; $i <= 255; $i++) {
- $rndkey[$i] = ord($cryptkey[$i % $key_length]);
- }
- for($j = $i = 0; $i < 256; $i++) {
- $j = ($j + $box[$i] + $rndkey[$i]) % 256;
- $tmp = $box[$i];
- $box[$i] = $box[$j];
- $box[$j] = $tmp;
- }
- for($a = $j = $i = 0; $i < $string_length; $i++) {
- $a = ($a + 1) % 256;
- $j = ($j + $box[$a]) % 256;
- $tmp = $box[$a];
- $box[$a] = $box[$j];
- $box[$j] = $tmp;
- $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
- }
- if($operation) {
- if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) &&
- substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
- return substr($result, 26);
- } else {
- return '';
- }
- } else {
- return $keyc.str_replace('=', '', base64_encode($result));
- }
- }
- static function randStr($randLength = 6, $addtime = 0, $includenumber = 0)
- {
- if ($includenumber) {
- $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789';
- } else {
- $chars = 'abcdefghijklmnopqrstuvwxyz';
- }
- $len = strlen($chars);
- $randStr = '';
- for ($i = 0; $i < $randLength; $i++) {
- $randStr .= $chars[mt_rand(0, $len - 1)];
- }
- $tokenvalue = $randStr;
- if ($addtime) {
- $tokenvalue = $randStr . time();
- }
- return $tokenvalue;
- }
- }
- // 批量加密
- function index(){
- ini_set('max_execution_time', 0);//秒为单位,自己根据需要定义
- set_time_limit(0);
- // $code = $this->arguments['code'];
- // $sta = $this->arguments['sta'];
- // $end = $this->arguments['end'];
- // var_dump($code,$sta,$end);
- // echo $res = Movies::_encrypt('123');
- // echo $res = Movies::_decrypt($res);
- $moviePath = FCPATH.'movie'.DIRECTORY_SEPARATOR; // 视频目录
- $data = [
- ['ID'=>1,'VideoFile'=>'huzongdieying.zip'],
- ['ID'=>2,'VideoFile'=>'27000084-bstg.mp4']
- ];
- $obj = new FilmFiles();
- foreach($data as $key=>$val){
- $filePath = $moviePath.$val['VideoFile'];
- $res = Movies::movieModify($filePath);
- if($res){
- $where = ['ID'=>$val['ID']];
- $info = [
- 'EncryptType'=>3,
- 'SecretKey'=>$res['Pkey'],
- 'SecretEncrypt'=>$res['passStr']
- ];
- $sta = $obj->updateLine($where,$info);
- var_dump($res,$sta);
- }
- }
- }
- // 批量解密
- function indexOut(){
- ini_set('max_execution_time', 0);//秒为单位,自己根据需要定义
- set_time_limit(0);
- $moviePath = FCPATH.'movie'.DIRECTORY_SEPARATOR;
- $data = [
- ['ID'=>1,'VideoFile'=>'a.mkv'],
- ['ID'=>2,'VideoFile'=>'b.mkv']
- ];
- $obj = new FilmFiles();
- $where = ['ID'=>1,'ID'=>2];
- $data = $obj->getList();
- foreach($data as $val){
- $filePath = $moviePath.$val->VideoFile;
- $res = Movies::movieReduction($filePath, $val->SecretEncrypt, $val->SecretKey);
- if($res){
- $where = ['ID'=>$val->ID];
- $info = [
- 'EncryptType'=>0,
- 'SecretKey'=>'',
- 'SecretEncrypt'=>''
- ];
- $sta = $obj->updateLine($where,$info);
- var_dump($res,$sta);
- }
- }
- }
以下是数据库类,可以参考
- <?php
- /*
- * js
- * Time 14:26
- * File FilmFiles.php
- * 数据库Model处理数据更改
- */
- namespace CoreModel\Payfilms;
- use Config\Database;
- class FilmFiles
- {
- //Model Path: CoreModel/Payfilms
- protected $db;
- protected $bld;
- public $Total = 0;
- public function __construct()
- {
- $connect = Database::connect();
- $this->db = &$connect;
- $this->bld = $this->db->table($this->Table);
- }
- private $Table = "payfilm_file";
- public $SelectFields = "ID,`DoubanID` ,`VideoFile` ,`VideoSize` ,`VideoMD5` ,`TorrentFile` ,`TorrentMD5` ,`FrameType` ,`Ratio` ,`Bitrate` ,`Format` ,`Acoustics` ,`SoundChannel` ,`EncryptType` ,`SecretKey` ,`SecretEncrypt`";
- function getCount($where = [])
- {
- $this->bld->select("count(ID) as Total");
- if (isset($where["limit"])) {
- unset($where["limit"]);
- }
- $this->where($where);
- $res = $this->bld->get()->getResultArray();
- log_message("debug", "CoreModel/Payfilms/FilmFiles ->getCount \nSQL: " . $this->db->getLastQuery());
- return $res[0]["Total"];
- }
- function where($where)
- {
- foreach ($where as $k => $v) {
- switch ($k) {
- case "ID":
- $this->bld->where("ID", $v);
- break;
- case "DoubanID":
- $this->bld->where("DoubanID", $v);
- break;
- case "VideoFile":
- $this->bld->where("VideoFile", $v);
- break;
- case "VideoSize":
- $this->bld->where("VideoSize", $v);
- break;
- case "VideoMD5":
- $this->bld->where("VideoMD5", $v);
- break;
- case "TorrentFile":
- $this->bld->where("TorrentFile", $v);
- break;
- case "TorrentMD5":
- $this->bld->where("TorrentMD5", $v);
- break;
- case "FrameType":
- $this->bld->where("FrameType", $v);
- break;
- case "Ratio":
- $this->bld->where("Ratio", $v);
- break;
- case "Bitrate":
- $this->bld->where("Bitrate", $v);
- break;
- case "Format":
- $this->bld->where("Format", $v);
- break;
- case "Acoustics":
- $this->bld->where("Acoustics", $v);
- break;
- case "SoundChannel":
- $this->bld->where("SoundChannel", $v);
- break;
- case "EncryptType":
- $this->bld->where("EncryptType", $v);
- break;
- case "SecretKey":
- $this->bld->where("SecretKey", $v);
- break;
- case "SecretEncrypt":
- $this->bld->where("SecretEncrypt", $v);
- break;
- case "operator":
- foreach ($v as $a => $b) {
- if (array_key_exists(0, $b)) {
- $this->bld->where($a . $b[0], $b[1]);
- continue;
- }
- foreach ($b as $n => $m) {
- $this->bld->where($a . $n, $m);
- }
- }
- break;
- case "between":
- foreach ($v as $a => $b) {
- $this->bld->where($a . ">=", $b[0]);
- $this->bld->where($a . "<=", $b[1]);
- }
- break;
- case "order_by":
- foreach ($v as $a => $b) {
- $this->bld->orderBy($a, $b);
- }
- break;
- case "not_in":
- foreach ($v as $a => $b) {
- $this->bld->whereNotIn($a, $b);
- }
- break;
- case "like":
- foreach ($v as $a => $b) {
- $this->bld->like($a, $b);
- }
- case "limit":
- $this->bld->limit($v, isset($where["offset"]) ? $where["offset"] : 0);
- break;
- }
- }
- }
- function getList($where = [])
- {
- $this->bld->select($this->SelectFields);
- $this->where($where);
- $this->Total = $this->bld->countAllResults(false);
- $res = $this->bld->get()->getResult();
- log_message("debug", "CoreModel/Payfilms/FilmFiles->getList \nSQL: " . $this->db->getLastQuery());
- if (count($res) > 0) {
- return $res;
- }
- return false;
- }
- function updateLine($where, $info)
- {
- $this->where($where);
- $data = [];
- foreach ($info as $k => $v) {
- switch ($k) {
- case "DoubanID":
- $data["DoubanID"] = $v;
- break;
- case "VideoFile":
- $data["VideoFile"] = $v;
- break;
- case "VideoSize":
- $data["VideoSize"] = $v;
- break;
- case "VideoMD5":
- $data["VideoMD5"] = $v;
- break;
- case "TorrentFile":
- $data["TorrentFile"] = $v;
- break;
- case "TorrentMD5":
- $data["TorrentMD5"] = $v;
- break;
- case "FrameType":
- $data["FrameType"] = $v;
- break;
- case "Ratio":
- $data["Ratio"] = $v;
- break;
- case "Bitrate":
- $data["Bitrate"] = $v;
- break;
- case "Format":
- $data["Format"] = $v;
- break;
- case "Acoustics":
- $data["Acoustics"] = $v;
- break;
- case "SoundChannel":
- $data["SoundChannel"] = $v;
- break;
- case "EncryptType":
- $data["EncryptType"] = $v;
- break;
- case "SecretKey":
- $data["SecretKey"] = $v;
- break;
- case "SecretEncrypt":
- $data["SecretEncrypt"] = $v;
- break;
- }
- }
- $this->bld->update($data);
- log_message("debug", "CoreModel/Payfilms/FilmFiles->updateLine \nSQL: " . $this->db->getLastQuery());
- if ($this->db->affectedRows() > 0) {
- return true;
- }
- return false;
- }
- function deleteLine($where)
- {
- $this->where($where);
- $this->bld->delete();
- log_message("debug", "CoreModel/Payfilms/FilmFiles->deleteLine \nSQL: " . $this->db->getLastQuery());
- if ($this->db->affectedRows() > 0) {
- return true;
- }
- return false;
- }
- function insertLine($info)
- {
- $data = [
- "DoubanID" => $info["DoubanID"],
- "VideoFile" => $info["VideoFile"],
- "VideoSize" => $info["VideoSize"],
- "VideoMD5" => $info["VideoMD5"],
- "TorrentFile" => $info["TorrentFile"],
- "TorrentMD5" => $info["TorrentMD5"],
- "FrameType" => $info["FrameType"],
- "Ratio" => $info["Ratio"],
- "Bitrate" => $info["Bitrate"],
- "Format" => $info["Format"],
- "Acoustics" => $info["Acoustics"],
- "SoundChannel" => $info["SoundChannel"],
- "EncryptType" => $info["EncryptType"],
- "SecretKey" => $info["SecretKey"],
- "SecretEncrypt" => $info["SecretEncrypt"],
- ];
- $this->bld->insert($data);
- log_message("debug", "CoreModel/Payfilms/FilmFiles->insertLine \nSQL: " . $this->db->getLastQuery());
- if ($this->db->affectedRows() > 0) {
- return $this->db->insertID();
- }
- return false;
- }
- function updateByID($ID, $info)
- {
- return $this->updateLine(["ID" => $ID], $info);
- }
- function getItemByID($ID)
- {
- $res = $this->getList(["ID" => $ID]);
- if (is_array($res)) {
- return $res[0];
- }
- return false;
- }
- function deleteByID($DoubanID)
- {
- return $this->deleteLine(["DoubanID" => $DoubanID]);
- }
- function getListByDouban($DoubanID, $Ext = [])
- {
- $where = ["DoubanID" => $DoubanID];
- $where = array_merge($where, $Ext);
- $res = $this->getList($where);
- if (is_array($res)) {
- return $res;
- }
- return false;
- }
- function deleteByDouban($DoubanID)
- {
- return $this->deleteLine(["DoubanID" => $DoubanID]);
- }
- }
PHP 视频源文件加密方案的更多相关文章
- lua 代码加密方案
require 实现 require函数在实现上是依次调用package.searchers(lua51中是package.loaders)中的载入函数,成功后返回.在loadlib.c文件里有四个载 ...
- 如何保护你的 Python 代码 (一)—— 现有加密方案
https://zhuanlan.zhihu.com/p/54296517 0 前言 去年11月在PyCon China 2018 杭州站分享了 Python 源码加密,讲述了如何通过修改 Pytho ...
- Atitit.视频文件加密的方法大的总结 java c# php
Atitit.视频文件加密的方法大的总结 java c# php 1. 加密的算法 aes 3des des xor等.1 2. 性能1 3. 解密1 4. 播放器的事件扩展1 5. 自定义格式 ...
- 一个异或加密方案--C语言实现
核心代码: char encrypt( char f , char c) { return f^c; } int OutEncrypt( char *FilePath, char *SecretWor ...
- C# .net 语言加密方案
C# .net 语言加密方案 方案背景 当前C# .net语言的应用范围越来越广泛,IIS 的服务器架构后台代码.桌面应用程序的 winform .Unity3d 的逻辑脚本都在使用.C# .net ...
- 基于HTTP在互联网传输敏感数据的消息摘要、签名与加密方案
基于HTTP在互联网传输敏感数据的消息摘要.签名与加密方案 博客分类: 信息安全 Java 签名加密AESMD5HTTPS 一.关键词 HTTP,HTTPS,AES,SHA-1,MD5,消息摘要,数 ...
- 网络摄像机进行互联网视频直播录像方案的选择,EasyNVS or EasyCloud or EasyGBS?
背景需求 互联网视频直播越来越成为当前大势:直播的需求往往都伴随在录像的需求,对于录像,不同的场景又有不同的方案选择: 本篇博客将会介绍对应的几种录像方案,可以帮助有互联网录像需求的用户进行对应的录像 ...
- [原创]aaencode等类似js加密方案破解方法
受http://tieba.baidu.com/p/4104806767 2L启发,不过他说的方法,我没有尝试成功,自己摸索出了一个新方法,在这里分享下. 首先拿aaencode官网的加密字符串作为例 ...
- nginx视频服务缓存方案设置指导
本文描述了如何通过设置nginx缓存达到降低服务器后端压力的效果以及结合nginx第三方插件ngx_cache_purge实现nginx缓存后的自动清理功能.具体实施步骤如下所示:第一步:获取清除清除 ...
- 基于RSA的WEB前端密码加密方案
受制于WEB页面源码的暴露,因此传统的对称加密方案以及加密密钥都将暴露在JS文件中,同样可以被解密. 目前比较好的解决方案是WEB页面全程或用户登录等关键环节使用HTTPS进行传输. 另外一种解决方案 ...
随机推荐
- Portainer 安装MySQL并开启远程访问
进入到 Portainer 页面,选择左边的 Containers 选项,单击上方的 Add container 按钮转到如图所示的页面: 1.在 Name 一栏中输入容器名字: 2.在 Image ...
- ELK 性能优化实践 ---总结篇
版本及硬件配置 JDK:JDK1.8_171-b11 (64 位) ES集群:由3台16核32G的虚拟机部署 ES 集群,每个节点分配 20 G 堆内存 ELK版本:6.3.0 垃圾回收器:ES 默认 ...
- 十分钟速成DevOps实践
摘要:以华为云软件开发平台DevCloud为例,十分钟简单体验下DevOps应用上云实践--H5经典小游戏上云. 本文分享自华为云社区<<DevOps实践秘籍>十分钟速成DevOps ...
- Springboot 之 Mybatis-plus 多数据源
简介 Mybatis-puls 多数据源的使用,采用的是官方提供的dynamic-datasource-spring-boot-starter包的 @DS 注解,具体可以参考官网: https://g ...
- CentOS 7.9 安装 kafka_2.13
一.CentOS 7.9 安装 kafka_2.13 地址 https://kafka.apache.org/downloads.html 二.安装准备 1 安装JDK 在安装kafka之前必须先安装 ...
- 2022年实时最新省市区县乡镇街道geojson行政边界数据获取方法
geojson 数据下载地址:https://hxkj.vip/demo/echartsMap/ 可下载的数据包含省级geojson行政边界数据.市级geojson行政边界数据.区/县级geojson ...
- 前端框架Vue------>第一天学习(3)
文章目录 8 .使用Axios实现异步通信 9 .表单输入绑定 9.1 . 什么是双向数据绑定 9.2 .为什么要实现数据的双向绑定 9.3 .在表单中使用双向数据绑定 8 .使用Axios实现异步通 ...
- 如何在IDEA中创建Module、以及怎样在IDEA中删除Module?
文章目录 1.为何要使用Module? 2.Module的创建 3.如何从硬盘上删除module 1.为何要使用Module? 目前主流的大型项目都是分布式部署的,结构类型这种多Module结构.不同 ...
- JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题
1.线程和进程 进程:一个程序,微信.qq...程序的集合.(一个进程包含多个线程,至少包含一个线程.java默认有两个线程:主线程(main).垃圾回收线程(GC) 线程:runnable.thre ...
- python dir函数解析
dir() 函数 不带参数,直接执行是返回当前环境中对象的名称列表.指定对象的名称作为参数执行,返回指定对象当中的属性(包括函数名,类名,变量名等) 下面我们具体找几个例子测试一下 dir() ...