對(duì)稱加密:
對(duì)稱加密是一種數(shù)據(jù)加密算法,對(duì)一組數(shù)據(jù)的加密和解密都使用一樣的密鑰(key),可以有效保護(hù)金融數(shù)據(jù),常見的對(duì)稱加密有DES,3DES,AES、RC2、RC4、RC5。
DES3:
對(duì)DES算法的組合,指定3個(gè)KEY,運(yùn)算3次DES,密鑰KEY的總字符長度為24位。
說明:
接觸這個(gè)主要是最近對(duì)接一個(gè)第三方的支付平臺(tái),調(diào)用他們的銀行卡,證件,姓名的鑒權(quán)接口,需要對(duì)一些特殊數(shù)字(銀行卡號(hào),身份證號(hào))進(jìn)行DES加密,再進(jìn)行簽名請(qǐng)求。其實(shí)這個(gè)主要就是用來做銀行卡綁定或者實(shí)名驗(yàn)證的。
流程:
1.客戶端輸入銀行卡卡號(hào),真實(shí)姓名,手機(jī)號(hào),身份證號(hào),手機(jī)號(hào)驗(yàn)證碼
2.通過匹配當(dāng)前用戶提交的驗(yàn)證碼和服務(wù)器上緩存的驗(yàn)證碼是否一致再進(jìn)行鑒權(quán)請(qǐng)求。
3.在支付后臺(tái)上拿到DES密鑰保存,對(duì)銀行卡號(hào),證件號(hào)等進(jìn)行DES加密。
4.通常鑒權(quán)請(qǐng)求為四要素(真實(shí)姓名,身份證號(hào),銀行卡號(hào),手機(jī)號(hào)[該卡預(yù)留號(hào)碼])
5.對(duì)請(qǐng)求參數(shù)進(jìn)行簽名,再發(fā)送請(qǐng)求,根據(jù)結(jié)果,認(rèn)證成功,則保存該用戶身份證號(hào),手機(jī)號(hào),銀行卡號(hào)。
其他:
中間用戶輸完銀行卡號(hào)時(shí),需要根據(jù)卡號(hào)識(shí)別出卡類型(什么銀行)和銀行編碼(全大寫英文,類似銀行的唯一id),記錄該銀行的聯(lián)行號(hào)(銀行的詳細(xì)信息編號(hào),精確到開戶銀行的省市區(qū),支行)更佳,因?yàn)橛袝r(shí)對(duì)公賬戶需要聯(lián)行號(hào)。這個(gè)識(shí)別接口可以去網(wǎng)上找,有免費(fèi)的,不過阿里云的接口更好用。
DES3類
<?php
namespace app\v1\extend;
class DES3{
//數(shù)據(jù)加密
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;
}
//數(shù)據(jù)解密
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);
}
}
?>
業(yè)務(wù)邏輯
protected $desKey = 'uMPE00c86bPWWyjLhBUlkA82'; // des加密密鑰
/**
* *鑒權(quán)請(qǐng)求
* @param [array] $[authParam] [綁卡基本信息輸入]
* @return [array] [接口信息反饋]
*/
public function verifyAuth($authParam) {
if (empty($authParam)) {
return false;
}
$Des3 = new DES3(); // 實(shí)例Des加密類
$paramReq = array(
'P1_bizType' => 'Authentication', // 交易類型
'P2_customerNumber' => $this->cusNum, // 商戶編號(hào)
'P3_orderId' => $authParam['orderNum'], // 商戶請(qǐng)求流水號(hào)
'P4_timestamp' => date('YmdHis'), // 時(shí)間戳
'P5_verifyType' => $this->authType, // 認(rèn)證類型
'P6_payerName' => $authParam['payerName'], // 姓名
'P7_idCardType' => 'IDCARD', // 證件類型
'P8_idCardNo' => $Des3->encrypt($authParam['idCardNo'],$this->desKey), // 證件號(hào)碼
'P9_cardNo' => $Des3->encrypt($authParam['cardNo'],$this->desKey), // 銀行卡號(hào)
'P10_year' => '', // 信用卡有效期年份
'P11_month' => '', // 信用卡有效期月份
'P12_cvv2' => '', // 信用卡安全碼
'P13_phone' => $Des3->encrypt($authParam['phoneNo'],$this->desKey), // 手機(jī)號(hào)碼
);
$preSignArr = array();
foreach($paramReq as $keys => $vals) {
$preSignArr[] = $vals;
}
// 組裝簽名
$paramReq['sign'] = $this->buildAuthSign($preSignArr, $this->authSignKey);
// 發(fā)起鑒權(quán)請(qǐng)求
$authReault = $this->curl_post($this->authHost, $paramReq);
return json_decode($authReault, true); // 返回請(qǐng)求結(jié)果
}
/**
* *生成鑒權(quán)請(qǐng)求簽名
* @param [array] $[authParam] [鑒權(quán)參數(shù)集]
* @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發(fā)起post請(qǐng)求
* @param [string] $[url] [請(qǐng)求地址]
* @param [array] $[params] [請(qǐng)求參數(shù)集]
* @return [返回結(jié)果集]
*/
protected function curl_post($url,$params) {
$ch = curl_init(); // 初始化curl
curl_setopt($ch,CURLOPT_URL,$url); // 抓取指定網(wǎng)頁
curl_setopt($ch, CURLOPT_HEADER, 0); // 設(shè)置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 要求結(jié)果為字符串且輸出到屏幕上
// curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_POST, 1); // post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$data = curl_exec($ch); // 運(yùn)行curl
curl_close($ch);
return($data); // 輸出結(jié)果