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

加密可实现的方式:修改视频字节流,只能替换字节流,例如头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 视频源文件加密方案的更多相关文章

  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. PostgreSQL 选择数据库

    数据库的命令窗口 PostgreSQL 命令窗口中,我们可以命令提示符后面输入 SQL 语句: postgres=# 使用 \l 用于查看已经存在的数据库: postgres=# \l List of ...

  2. typescript中对象属性可选属性与只读属性与索引签名

    可选属性 type类型别名 type 会给一个类型起个新名字. type 有时和 interface 很像,但是可以作用于原始值(基本类型),联合类型,元组以及其它任何你需要手写的类型. interf ...

  3. 在 WPF 中实现融合效果

    1. 融合效果 融合效果是指对两个接近的元素进行高斯模糊后再提高对比度,使它们看上去"粘"在一起.在之前的一篇文章中,我使用 Win2D 实现了融合效果,效果如下: 不过 Win2 ...

  4. Linux shell猜数游戏

    题目:猜随机数随机1-100中的一个数字,要求用户猜数字,猜中则退出脚本并告知用户猜测次 数和随机数字,否则要求用户继续猜,并告知当前猜的数字和随机数的关系. #!/bin/bash #猜数游戏 Ra ...

  5. Android自动化测试工具调研

    原文地址:Android自动化测试工具调研 - Stars-One的杂货小窝 Android测试按测试方式分类,可分为两种:一种是传统逻辑单元测试(Junit),另外一种则是UI交互页面测试. 这里详 ...

  6. java 新特性之 Stream API

    强大的 Stream API 一.Stream API 的概述 Stream到底是什么呢? 是数据渠道,用于操作数据源(集合.数组等)所生成的元素序列. "集合讲的是数据,Stream讲的是 ...

  7. 七、docker镜像私有仓库

    在Docker中,当我们执行 docker pull xxx 的时候 ,它实际上是从 hub.docker.com 这个地址去查找,这就是 Docker 公司为我们提供的公共仓库.在工作中,我们不可能 ...

  8. 云原生之旅 - 6)不能错过的一款 Kubernetes 应用编排管理神器 Kustomize

    前言 相信经过前一篇文章的学习,大家已经对Helm有所了解,本篇文章介绍另一款工具 Kustomize,为什么Helm如此流行,还会出现 Kustomize?而且 Kustomize 自 kubect ...

  9. RHCE习题

    RHCE习题 考试说明: RH294系统信息 在练习期间,您将操作下列虚拟系统: 真实机: foundation: kiosk:redhat root: Asimov workstation.lab. ...

  10. Go map 竟然也会发生内存泄露?

    Go 程序运行时,有些场景下会导致进程进入某个"高点",然后就再也下不来了. 比如,多年前曹大写过的一篇文章讲过,在做活动时线上涌入的大流量把 goroutine 数抬升了不少,流 ...