对称加密:

对称加密是一种数据加密算法,对一组数据的加密和解密都使用一样的密钥(key),可以有效保护金融数据,常见的对称加密有DES,3DES,AES、RC2、RC4、RC5。DES3: 对DES算法的组合,指定3个KEY,运算3次DES,密钥KEY的总字符长度为24位。

说明:

接触这个主要是最近对接一个第三方的支付平台,调用他们的银行卡,证件,姓名的鉴权接口,需要对一些特殊数字(银行卡号,身份证号)进行DES加密,再进行签名请求。其实这个主要就是用来做银行卡绑定或者实名验证的。

流程:

1.客户端输入银行卡卡号,真实姓名,手机号,身份证号,手机号验证码
2.通过匹配当前用户提交的验证码和服务器上缓存的验证码是否一致再进行鉴权请求。
3.在支付后台上拿到DES密钥保存,对银行卡号,证件号等进行DES加密。
4.通常鉴权请求为四要素(真实姓名,身份证号,银行卡号,手机号)
5.对请求参数进行签名,再发送请求,根据结果,认证成功,则保存该用户身份证号,手机号,银行卡号。

其他:

中间用户输完银行卡号时,需要根据卡号识别出卡类型(什么银行)和银行编码(全大写英文,类似银行的唯一id),记录该银行的联行号(银行的详细信息编号,精确到开户银行的省市区,支行)更佳,因为有时对公账户需要联行号。这个识别接口可以去网上找,有免费的,不过阿里云的接口更好用。

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

?> 

业务逻辑

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);          // 输出结果            
}