對稱加密:對稱加密是一種數據加密算法,對一組數據的加密和解密都使用同樣的密鑰(key),能夠有效保護金融數據,常見的對稱加密有DES,3DES,AES、RC二、RC四、RC5。php
DES3: 對DES算法的組合,指定3個KEY,運算3次DES,密鑰KEY的總字符長度爲24位。算法
說明: 接觸這個主要是最近對接一個第三方的支付平臺,調用他們的銀行卡,證件,姓名的鑑權接口,須要對一些特殊數字(銀行卡號,身份證號)進行DES加密,再進行簽名請求。其實這個主要就是用來作銀行卡綁定或者實名驗證的。json
流程:緩存
1.客戶端輸入銀行卡卡號,真實姓名,手機號,身份證號,手機號驗證碼安全
2.經過匹配當前用戶提交的驗證碼和服務器上緩存的驗證碼是否一致再進行鑑權請求。服務器
3.在支付後臺上拿到DES密鑰保存,對銀行卡號,證件號等進行DES加密。app
4.一般鑑權請求爲四要素(真實姓名,身份證號,銀行卡號,手機號[該卡預留號碼])curl
5.對請求參數進行簽名,再發送請求,根據結果,認證成功,則保存該用戶身份證號,手機號,銀行卡號。post
附: 中間用戶輸完銀行卡號時,須要根據卡號識別出卡類型(什麼銀行)和銀行編碼(全大寫英文,相似銀行的惟一id),記錄該銀行的聯行號(銀行的詳細信息編號,精確到開戶銀行的省市區,支行)更佳,由於有時對公帳戶須要聯行號。這個識別接口能夠去網上找,有免費的,不過阿里雲的接口更好用。ui
1、DES3類
<?php namespace app\v1\extend; class DES3{ //數據加密 function encrypt($input, $key) { $size = mcrypt_get_block_size(MCRYPT_3DES,'ecb'); $input = $this->pkcs5_pad($input, $size); $key = str_pad($key,24,'0'); $td = mcrypt_module_open(MCRYPT_3DES, '', 'ecb', ''); $iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); @mcrypt_generic_init($td, $key, $iv); $data = mcrypt_generic($td, $input); mcrypt_generic_deinit($td); mcrypt_module_close($td); $data = base64_encode($data); return $data; } //數據解密 function decrypt($encrypted, $key) { $encrypted = base64_decode($encrypted); $key = str_pad($key,24,'0'); $td = mcrypt_module_open(MCRYPT_3DES,'','ecb',''); $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND); $ks = mcrypt_enc_get_key_size($td); @mcrypt_generic_init($td, $key, $iv); $decrypted = mdecrypt_generic($td, $encrypted); mcrypt_generic_deinit($td); mcrypt_module_close($td); $y=$this->pkcs5_unpad($decrypted); return $y; } function pkcs5_pad ($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } function pkcs5_unpad($text) { $pad = ord($text{strlen($text)-1}); if ($pad > strlen($text)) { return false; } if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) { return false; } return substr($text, 0, -1 * $pad); } } ?>
2、業務邏輯
protected $desKey = 'uMPE00c86bPWWyjLhBUlkA82'; // des加密密鑰 /** * *鑑權請求 * @param [array] $[authParam] [綁卡基本信息輸入] * @return [array] [接口信息反饋] */ public function verifyAuth($authParam) { if (empty($authParam)) { return false; } $Des3 = new DES3(); // 實例Des加密類 $paramReq = array( 'P1_bizType' => 'Authentication', // 交易類型 'P2_customerNumber' => $this->cusNum, // 商戶編號 'P3_orderId' => $authParam['orderNum'], // 商戶請求流水號 'P4_timestamp' => date('YmdHis'), // 時間戳 'P5_verifyType' => $this->authType, // 認證類型 'P6_payerName' => $authParam['payerName'], // 姓名 'P7_idCardType' => 'IDCARD', // 證件類型 'P8_idCardNo' => $Des3->encrypt($authParam['idCardNo'],$this->desKey), // 證件號碼 'P9_cardNo' => $Des3->encrypt($authParam['cardNo'],$this->desKey), // 銀行卡號 'P10_year' => '', // 信用卡有效期年份 'P11_month' => '', // 信用卡有效期月份 'P12_cvv2' => '', // 信用卡安全碼 'P13_phone' => $Des3->encrypt($authParam['phoneNo'],$this->desKey), // 手機號碼 ); $preSignArr = array(); foreach($paramReq as $keys => $vals) { $preSignArr[] = $vals; } // 組裝簽名 $paramReq['sign'] = $this->buildAuthSign($preSignArr, $this->authSignKey); // 發起鑑權請求 $authReault = $this->curl_post($this->authHost, $paramReq); return json_decode($authReault, true); // 返回請求結果 } /** * *生成鑑權請求籤名 * @param [array] $[authParam] [鑑權參數集] * @return [string] [md5簽名串] */ protected function buildAuthSign($authParam,$signKey) { $reqStr = ""; foreach($authParam as $keys=>$vals) { $reqStr .= '&'.$vals; } // if(!$key) { // return md5($reqStr); // die; // } // return $key; // die; //$newSign = $reqStr.'&'.$signKey; $newSign = md5($reqStr.'&'.$signKey); return $newSign; } /** * *curl發起post請求 * @param [string] $[url] [請求地址] * @param [array] $[params] [請求參數集] * @return [返回結果集] */ protected function curl_post($url,$params) { $ch = curl_init(); // 初始化curl curl_setopt($ch,CURLOPT_URL,$url); // 抓取指定網頁 curl_setopt($ch, CURLOPT_HEADER, 0); // 設置header curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 要求結果爲字符串且輸出到屏幕上 // curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_POST, 1); // post提交方式 curl_setopt($ch, CURLOPT_POSTFIELDS, $params); $data = curl_exec($ch); // 運行curl curl_close($ch); return($data); // 輸出結果 }
我的公衆號