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)); } } }