rsa非对称加密

加密概要

加密技术是对信息进行编码和解码的技术,编码是把原来可读信息(又称明文)译成代码形式(又称密文),其逆过程就是解码(解密),加密技术的要点是加密算法,加密算法可以分为三类: 
1. 对称加密 
2. 非对称加密 
3. 不可逆加密

https://blog.csdn.net/qwe6112071/article/details/53576584

非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;
如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

https://blog.csdn.net/lmjy102/article/details/53540805

 

学习源头:

https://blog.csdn.net/zhongyuchuan147/article/details/78367031

/*****************************************

加密是为了数据安全 一般用在有接口的场景中

分为后端之间的接口加密和前后端的接口对接

1.后端 第三方和平台的对接

 https://www.cnblogs.com/CraryPrimitiveMan/p/6242167.html?utm_source=itdadao&utm_medium=referral

2.前后端的对接 jsencrypt

 https://www.cnblogs.com/CraryPrimitiveMan/p/6242167.html?utm_source=itdadao&utm_medium=referral

3.同学微信公众号项目 vue和php的对接

同步验证登录

 

 

 

 

 

加密文件

<?php
/**
 * 数据管理
 * User: djw
 * Date: 2018/5/24
 * Time: 14:45
 */

namespace ai\Http\Controllers;


use ai\Lib\Secrets;
use ClassesWithParents\D;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class Data extends Controller
{
    /**
     * 导入数据
     */
    public function import(Request $request)
    {
        if ($request->isMethod('get')) {
//            phpinfo();die;
            return view('data.import');
        } else {
            $name = $request->name;
            $bus = $request->bus;
            $task = $request->task;
            $huashu = $request->huashu;
            $data_file = $request->file('data');
            if($data_file -> isValid()) { //检验一下上传的文件是否有效.
                $clientName = $data_file->getClientOriginalName();
                $pack_name = substr($clientName, 0, strrpos($clientName, '.')); // 包名
            }

            $dst_path = Config::get('constants.UPLOAD_DATA').'/'.date('Y', time()) . '/' . date('m', time()) . '/' . date('d', time());
            // 这里是如果上传文件过大 自己命令文件的处理代码
//            $newName = md5(date("Y-m-d H:i:s").mt_rand(1000,9999));
//            $entension = $data_file -> getClientOriginalExtension();
//            $path = $request->file('data')->storeAs(
//                $dst_path, $newName.'.'.$entension
//            );
            $path = $request->file('data')->store($dst_path);
//            $path = Storage::putFile('uploadData', $request->file('data'));
            $import_time= time();
            $status = 2; // 默认为2 未完成
            $operation = 2; // 默认为2 未完成 对应的关闭
            $task_type = \ai\Models\Task::getTaskType($bus, $task);
            $task_type = $task_type->type;
//            dd($task_type->type);
//            dd($path);
            $data = $this->importData(public_path().'/upload/'.$path, $huashu, $pack_name);
            $result = post_api($post_url, $data);
            dd($result);
            $res = DB::table('a_data_packet')->insert(['name' => $name, 'business_id' => $bus, 'task_id' => $task, 'huashu_id' => $huashu, 'data_position' => $path, 'import_time' => $import_time, 'operation' => $operation,'status' => $status,'task_type' => $task_type]);
            if ($res) {
                return view('data.import', ['message' => '导入数据成功']);
            }
        }

    }

    /** 筛选任务数据管理页面
     */
    public function screenTask(Request $request)
    {
        // 搜索条件 数据包名 数据包ID 任务名称 商家名称 状态
        $data_name = $request->data_name ? $request->data_name : '';
        $data_id = $request->data_id ? $request->data_id : '';
        $task_name = $request->task_name ? $request->task_name : '';
        $bus_name = $request->bus_name ? $request->bus_name : '';
        $status = $request->status;
        $task_type = 1;
        $datas = $this->getData($data_name, $data_id, $task_name, $bus_name, $status, $task_type);
//        dd($datas);

        // 分页
        $perPage = Config::get('constants.PERPAGE');
        if ($request->has('page')) {
            $current_page = $request->input('page');
            $current_page = $current_page <= 0 ? 1 :$current_page;
        } else {
            $current_page = 1;
        }
        $data = Business::fenye($perPage, $current_page, $datas);

        $data = [
            'datas' => $data[0],
            'paginator' => $data[1],
            'total' => $data[2],
            'data_name' => $data_name,
            'data_id' => $data_id,
            'task_name' => $task_name,
            'bus_name' => $bus_name,
            'status' => $status,
        ];

        return view('data.screenTask.index')
            ->with($data)
            ;
    }

    private function getData($data_name, $data_id, $task_name, $bus_name, $status, $task_type)
    {
        $data_name = trim($data_name);
        $data_id = trim($data_id);
        $task_name = trim($task_name);
        $bus_name = trim($bus_name);

        $where_str = ' where 1 = 1';
        if ($data_name) {
            $where_str .= " AND d.name like '%$task_name%'";
        }
        if ($data_id) {
            $where_str .= " AND d.id = $data_id";
        }
        if ($bus_name) {
            $where_str .= " AND b.name like '%$bus_name%'";
        }
        if ($task_name) {
            $where_str .= " AND t.name like '%$task_name%'";
        }
        if ($status) {
            $where_str .= " AND d.status = $status";
        }
        if ($task_type) {
            $where_str .= " AND d.task_type = $task_type";
        }

        $sql = "SELECT d.*, b.name as b_name, t.name as t_name FROM a_data_packet as d LEFT JOIN a_business as b ON d.business_id = b.id LEFT JOIN a_task as t ON d.task_id = t.id";
        $sql .= $where_str;
        $sql .= " ORDER BY d.status asc";

        $res = DB::select($sql);

        return $res;
    }

    /**
     * ajax 发布
     */
    public function release(Request $request)
    {
        $id = $request->id;
        $res = DB::table('a_data_packet')->where('id', $id)->update(['operation' => 3, 'status' => '3']);

        if ($res) {
            return ['status' => 1]; // 成功
        }
    }

    /**
     * ajax 关闭
     */
    public function close(Request $request)
    {
        $id = $request->id;
        $res = DB::table('a_data_packet')->where('id', $id)->update(['operation' => 4, 'status' => '3']);

        if ($res) {
            return ['status' => 1]; // 成功
        }
    }

    /**
     * 筛选数据
     */
    public function screen(Request $request)
    {

    }

    /** 转接任务数据管理页面
     */
    public function transferTask(Request $request)
    {
        // 搜索条件 数据包名 数据包ID 任务名称 商家名称 状态
        $data_name = $request->data_name ? $request->data_name : '';
        $data_id = $request->data_id ? $request->data_id : '';
        $task_name = $request->task_name ? $request->task_name : '';
        $bus_name = $request->bus_name ? $request->bus_name : '';
        $status = $request->status;
        $task_type = 2;
        $datas = $this->getData($data_name, $data_id, $task_name, $bus_name, $status, $task_type);
//        dd($datas);

        // 分页
        $perPage = Config::get('constants.PERPAGE');
        if ($request->has('page')) {
            $current_page = $request->input('page');
            $current_page = $current_page <= 0 ? 1 :$current_page;
        } else {
            $current_page = 1;
        }
        $data = Business::fenye($perPage, $current_page, $datas);

        $data = [
            'datas' => $data[0],
            'paginator' => $data[1],
            'total' => $data[2],
            'data_name' => $data_name,
            'data_id' => $data_id,
            'task_name' => $task_name,
            'bus_name' => $bus_name,
            'status' => $status,


]; return view('data.transferTask.index') ->with($data) ; } /** 拨打任务数据管理页面 */ public function dialTask(Request $request) { // 搜索条件 数据包名 数据包ID 任务名称 商家名称 状态 $data_name = $request->data_name ? $request->data_name : ''; $data_id = $request->data_id ? $request->data_id : ''; $task_name = $request->task_name ? $request->task_name : ''; $bus_name = $request->bus_name ? $request->bus_name : ''; $status = $request->status; $task_type = 3; $datas = $this->getData($data_name, $data_id, $task_name, $bus_name, $status, $task_type); // dd($datas); // 分页 $perPage = Config::get('constants.PERPAGE'); if ($request->has('page')) { $current_page = $request->input('page'); $current_page = $current_page <= 0 ? 1 :$current_page; } else { $current_page = 1; } $data = Business::fenye($perPage, $current_page, $datas); $data = [ 'datas' => $data[0], 'paginator' => $data[1], 'total' => $data[2], 'data_name' => $data_name, 'data_id' => $data_id, 'task_name' => $task_name, 'bus_name' => $bus_name, 'status' => $status, ]; return view('data.dialTask.index') ->with($data) ; } /** * 导入数据接口 */ public function importData($path, $speech_id, $pack_name) { $contents = file_get_contents($path); $contents=str_replace(array("\n","\r"),"",trim($contents)); $phone_arr = str_split($contents, 11); $file = []; foreach ($phone_arr as $key=>$value) { $file[$key]['number'] = $value; // 数据 $file[$key]['data_id'] = time().$key; // 数据id } $app_id = 1; $time_stamp = time(); $signInfo = $app_id.$time_stamp; $public_key = Config::get('constants.PUBLIC_KEY'); $pu_key = openssl_pkey_get_public($public_key);// 可用返回资源id $public_encrypt = Secrets::public_encrypt($signInfo,$pu_key);//加密 $signInfo = urlencode($public_encrypt); // $signInfo = $public_encrypt; // var_dump($signInfo); $data = ['file' => $file, 'speech_id' => $speech_id, 'pack_name' => $pack_name, 'time_stamp' => $time_stamp, 'app_id' => $app_id, "signInfo" => $signInfo]; $data= json_encode($data); // dd($signInfo, $data); return $data; } }

使用
 $app_id = 1;
        $time_stamp = time();
        $signInfo = $app_id.$time_stamp;
        $public_key = Config::get('constants.PUBLIC_KEY');
        $pu_key = openssl_pkey_get_public($public_key);// 可用返回资源id
        $public_encrypt = Secrets::public_encrypt($signInfo,$pu_key);//加密
        $signInfo = urlencode($public_encrypt);

 这是公私钥的类

<?php
/**
 * Created by PhpStorm.
 * User: han
 * Date: 2017/2/13
 * Time: 16:34
 */
namespace ai\Lib;

class Secrets {
    private $public_key = ''; //公密钥
    private $private_key = ''; //私密钥
    private $public_key_resource = ''; //公密钥资源
    private $private_key_resource = ''; //私密钥资源
    private $public_key_file = '/'; //公密钥文件地址
    private $private_key_file = ''; //私密钥文件地址
    /**
     * 架构函数
     * @param [string] $public_key_file  [公密钥文件地址]
     * @param [string] $private_key_file [私密钥文件地址]
//     */
//    public function __construct($public_key_file,$private_key_file) {
//        try {
//            if(!file_exists($public_key_file) || !file_exists($private_key_file)) {
//                throw new Exception('key file no exists');
//            }
//            if (false == ($this->public_key = file_get_contents($public_key_file)) || false == ($this->private_key = file_get_contents($private_key_file))) {
//                throw new Exception('read key file fail');
//            }
//            if(false == ($this->public_key_resource = $this->is_bad_public_key($this->public_key)) || false == ($this->private_key_resource = $this->is_bad_private_key($this->private_key))) {
//                throw new Exception('public key or private key no usable');
//            }
//
//        } catch (Exception $e) {
//            die($e->getMessage());
//        }
//    }
    private function is_bad_public_key($public_key) {
        return openssl_pkey_get_public($public_key);
    }
    private function is_bad_private_key($private_key) {
        return openssl_pkey_get_private($private_key);
    }
    /**
     * 生成一对公私密钥 成功返回 公私密钥数组 失败 返回 false
     */
    public function create_key() {
        $res = openssl_pkey_new();
        if($res == false) return false;
        openssl_pkey_export($res, $private_key);
        $public_key = openssl_pkey_get_details($res);
        return array('public_key'=>$public_key["key"],'private_key'=>$private_key);
    }
    /**
     * 用私密钥加密
     */
    public function private_encrypt($input,$private_key_resource) {
        //openssl_private_encrypt($input,$output,$this->private_key_resource);
        openssl_private_encrypt($input,$output,$private_key_resource);
        return base64_encode($output);
    }
    /**
     * 解密 私密钥加密后的密文
     */
    public function public_decrypt($input) {
        openssl_public_decrypt(base64_decode($input),$output,$this->public_key_resource);
        return $output;
    }
    /**
     * 用公密钥加密
     */
    public static function public_encrypt($input,$public_key_resource) {
        openssl_public_encrypt($input,$output,$public_key_resource);
        return base64_encode($output);
    }
    /**
     * 解密 公密钥加密后的密文
     */
    public function private_decrypt($input,$private_key_resource) {
        openssl_private_decrypt(base64_decode($input),$output,$private_key_resource);
        return $output;
    }


    /**
     * @param $string 字符串 明文或密文
     * @param string $operation DECODE表示解密 其它表示加密
     * @param string $key 密匙
     * @param int $expiry 密文有效期
     * @return string
     * @Author guozm@uway.cn Jhonny
     * @Date 2017/02/17 16:00
     */
    function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
        // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
        $ckey_length = 4;
        // 密匙
        $key = md5($key ? $key : $GLOBALS['discuz_auth_key']);
        // 密匙a会参与加解密
        $keya = md5(substr($key, 0, 16));
        // 密匙b会用来做数据完整性验证
        $keyb = md5(substr($key, 16, 16));
        // 密匙c用于变化生成的密文
        $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length):
            substr(md5(microtime()), -$ckey_length)) : '';
        // 参与运算的密匙
        $cryptkey = $keya.md5($keya.$keyc);
        $key_length = strlen($cryptkey);
        // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),
        //解密时会通过这个密匙验证数据完整性
        // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确
        $string = $operation == 'DECODE' ? 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 == 'DECODE') {
            // 验证数据有效性,请看未加密明文的格式
            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 {
            // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因
            // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码
            return $keyc.str_replace('=', '', base64_encode($result));
        }
    }
}

 

posted @ 2018-05-28 17:49  段佳伟  阅读(453)  评论(0编辑  收藏  举报