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 视频源文件加密方案

上一篇:PHP 实现大文件视频推流


下一篇:centos下.Netcore的docker容器部署出现“The type initializer for 'Gdip' threw an exception.”