• PHP 视频源文件加密方案


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

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

    下面上代码吧,加解密是

    openssl_encrypt
    openssl_decrypt
    <?php
    /**
     * 
     * Created by PhpStorm.
     * User: js
     * Date: 2021/04/15
     * Time: 17:03
     * PhpStorm
     */
    
    namespace CoreModelPayfilms;
    
    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 CoreModelPayfilms;
    
    use ConfigDatabase;
    
    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 
    SQL: " . $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 
    SQL: " . $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 
    SQL: " . $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 
    SQL: " . $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 
    SQL: " . $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]);
        }
    }
    分享技术,方便你我他。
  • 相关阅读:
    前端-html/css
    数据结构-python
    接口测试-并发处理
    接口测试-高级运用
    接口测试-模拟网络请求
    接口测试-基础
    Jenkins-基础
    appium安装及环境搭建、入门
    Week12-unittest单元测试
    Redis在windows下安装与配置
  • 原文地址:https://www.cnblogs.com/leijiangsheng/p/14678359.html
Copyright © 2020-2023  润新知