273 lines
6.1 KiB
PHP
273 lines
6.1 KiB
PHP
<?php
|
|
|
|
// 初始化日志
|
|
global $log;
|
|
$log = new PhpLog ( SDK_LOG_FILE_PATH,"PRC",SDK_LOG_LEVEL );
|
|
|
|
/**
|
|
* 签名
|
|
*
|
|
* @param String $params_str
|
|
*/
|
|
function sign(&$params, $cert_path, $cert_pwd) {
|
|
global $log;
|
|
|
|
$log->LogInfo ( '=====签名报文开始======' );
|
|
if(isset($params['signature'])){
|
|
unset($params['signature']);
|
|
}
|
|
// 转换成key=val&串
|
|
$params_str = createLinkString ( $params, true, false );
|
|
$log->LogInfo ( "签名key=val&...串 >" . $params_str );
|
|
|
|
$params_sha1x16 = sha1 ( $params_str, FALSE );
|
|
$log->LogInfo ( "摘要sha1x16 >" . $params_sha1x16 );
|
|
|
|
$private_key = getPrivateKey ( $cert_path, $cert_pwd );
|
|
// 签名
|
|
$sign_falg = openssl_sign ( $params_sha1x16, $signature, $private_key, OPENSSL_ALGO_SHA1 );
|
|
if ($sign_falg) {
|
|
$signature_base64 = base64_encode ( $signature );
|
|
$log->LogInfo ( "签名串为 >" . $signature_base64 );
|
|
$params ['signature'] = $signature_base64;
|
|
} else {
|
|
$log->LogInfo ( ">>>>>签名失败<<<<<<<" );
|
|
}
|
|
$log->LogInfo ( '=====签名报文结束======' );
|
|
}
|
|
|
|
/**
|
|
* 验签
|
|
*
|
|
* @param String $params_str
|
|
* @param String $signature_str
|
|
*/
|
|
function verify($params) {
|
|
global $log;
|
|
// 公钥
|
|
$public_key = getPulbicKeyByCertId ( $params ['certId'] );
|
|
// echo $public_key.'<br/>';
|
|
// 签名串
|
|
$signature_str = $params ['signature'];
|
|
unset ( $params ['signature'] );
|
|
$params_str = createLinkString ( $params, true, false );
|
|
$log->LogInfo ( '报文去[signature] key=val&串>' . $params_str );
|
|
$signature = base64_decode ( $signature_str );
|
|
// echo date('Y-m-d',time());
|
|
$params_sha1x16 = sha1 ( $params_str, FALSE );
|
|
$log->LogInfo ( '摘要shax16>' . $params_sha1x16 );
|
|
$isSuccess = openssl_verify ( $params_sha1x16, $signature,$public_key, OPENSSL_ALGO_SHA1 );
|
|
$log->LogInfo ( $isSuccess ? '验签成功' : '验签失败' );
|
|
return $isSuccess;
|
|
}
|
|
|
|
/**
|
|
* 根据证书ID 加载 证书
|
|
*
|
|
* @param unknown_type $certId
|
|
* @return string NULL
|
|
*/
|
|
function getPulbicKeyByCertId($certId) {
|
|
global $log;
|
|
$log->LogInfo ( '报文返回的证书ID>' . $certId );
|
|
// 证书目录
|
|
$cert_dir = SDK_VERIFY_CERT_DIR;
|
|
$log->LogInfo ( '验证签名证书目录 :>' . $cert_dir );
|
|
$handle = opendir ( $cert_dir );
|
|
if ($handle) {
|
|
while ( $file = readdir ( $handle ) ) {
|
|
clearstatcache ();
|
|
$filePath = $cert_dir . '/' . $file;
|
|
if (is_file ( $filePath )) {
|
|
if (pathinfo ( $file, PATHINFO_EXTENSION ) == 'cer') {
|
|
if (getCertIdByCerPath ( $filePath ) == $certId) {
|
|
closedir ( $handle );
|
|
$log->LogInfo ( '加载验签证书成功' );
|
|
return getPublicKey ( $filePath );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$log->LogInfo ( '没有找到证书ID为[' . $certId . ']的证书' );
|
|
} else {
|
|
$log->LogInfo ( '证书目录 ' . $cert_dir . '不正确' );
|
|
}
|
|
closedir ( $handle );
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 取证书ID(.pfx)
|
|
*
|
|
* @return unknown
|
|
*/
|
|
function getSignCertId($cert_path, $cert_pwd) {
|
|
$pkcs12certdata = file_get_contents ( $cert_path );
|
|
openssl_pkcs12_read ( $pkcs12certdata, $certs, $cert_pwd );
|
|
$x509data = $certs ['cert'];
|
|
openssl_x509_read ( $x509data );
|
|
$certdata = openssl_x509_parse ( $x509data );
|
|
$cert_id = $certdata ['serialNumber'];
|
|
|
|
return $cert_id;
|
|
}
|
|
|
|
/**
|
|
* 取证书ID(.cer)
|
|
*
|
|
* @param unknown_type $cert_path
|
|
*/
|
|
function getCertIdByCerPath($cert_path) {
|
|
$x509data = file_get_contents ( $cert_path );
|
|
openssl_x509_read ( $x509data );
|
|
$certdata = openssl_x509_parse ( $x509data );
|
|
$cert_id = $certdata ['serialNumber'];
|
|
return $cert_id;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* 取证书公钥 -验签
|
|
*
|
|
* @return string
|
|
*/
|
|
function getPublicKey($cert_path) {
|
|
return file_get_contents ( $cert_path );
|
|
}
|
|
/**
|
|
* 返回(签名)证书私钥 -
|
|
*
|
|
* @return unknown
|
|
*/
|
|
function getPrivateKey($cert_path=SDK_SIGN_CERT_PATH, $cert_pwd=SDK_SIGN_CERT_PWD) {
|
|
$pkcs12 = file_get_contents ( $cert_path );
|
|
openssl_pkcs12_read ( $pkcs12, $certs, $cert_pwd );
|
|
return $certs ['pkey'];
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Author: gu_yongkang
|
|
* data: 20110510
|
|
* 密码转PIN
|
|
* Enter description here ...
|
|
* @param $spin
|
|
*/
|
|
function Pin2PinBlock( &$sPin )
|
|
{
|
|
// $sPin = "123456";
|
|
$iTemp = 1;
|
|
$sPinLen = strlen($sPin);
|
|
$sBuf = array();
|
|
//密码域大于10位
|
|
$sBuf[0]=intval($sPinLen, 10);
|
|
|
|
if($sPinLen % 2 ==0)
|
|
{
|
|
for ($i=0; $i<$sPinLen;)
|
|
{
|
|
$tBuf = substr($sPin, $i, 2);
|
|
$sBuf[$iTemp] = intval($tBuf, 16);
|
|
unset($tBuf);
|
|
if ($i == ($sPinLen - 2))
|
|
{
|
|
if ($iTemp < 7)
|
|
{
|
|
$t = 0;
|
|
for ($t=($iTemp+1); $t<8; $t++)
|
|
{
|
|
$sBuf[$t] = 0xff;
|
|
}
|
|
}
|
|
}
|
|
$iTemp++;
|
|
$i = $i + 2; //linshi
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for ($i=0; $i<$sPinLen;)
|
|
{
|
|
if ($i ==($sPinLen-1))
|
|
{
|
|
$mBuf = substr($sPin, $i, 1) . "f";
|
|
$sBuf[$iTemp] = intval($mBuf, 16);
|
|
unset($mBuf);
|
|
if (($iTemp)<7)
|
|
{
|
|
$t = 0;
|
|
for ($t=($iTemp+1); $t<8; $t++)
|
|
{
|
|
$sBuf[$t] = 0xff;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$tBuf = substr($sPin, $i, 2);
|
|
$sBuf[$iTemp] = intval($tBuf, 16);
|
|
unset($tBuf);
|
|
}
|
|
$iTemp++;
|
|
$i = $i + 2;
|
|
}
|
|
}
|
|
return $sBuf;
|
|
}
|
|
/**
|
|
* Author: gu_yongkang
|
|
* data: 20110510
|
|
* Enter description here ...
|
|
* @param $sPan
|
|
*/
|
|
function FormatPan(&$sPan)
|
|
{
|
|
$iPanLen = strlen($sPan);
|
|
$iTemp = $iPanLen - 13;
|
|
$sBuf = array();
|
|
$sBuf[0] = 0x00;
|
|
$sBuf[1] = 0x00;
|
|
for ($i=2; $i<8; $i++)
|
|
{
|
|
$tBuf = substr($sPan, $iTemp, 2);
|
|
$sBuf[$i] = intval($tBuf, 16);
|
|
$iTemp = $iTemp + 2;
|
|
}
|
|
return $sBuf;
|
|
}
|
|
|
|
function Pin2PinBlockWithCardNO(&$sPin, &$sCardNO)
|
|
{
|
|
global $log;
|
|
$sPinBuf = Pin2PinBlock($sPin);
|
|
$iCardLen = strlen($sCardNO);
|
|
// $log->LogInfo("CardNO length : " . $iCardLen);
|
|
if ($iCardLen <= 10)
|
|
{
|
|
return (1);
|
|
}
|
|
elseif ($iCardLen==11){
|
|
$sCardNO = "00" . $sCardNO;
|
|
}
|
|
elseif ($iCardLen==12){
|
|
$sCardNO = "0" . $sCardNO;
|
|
}
|
|
$sPanBuf = FormatPan($sCardNO);
|
|
$sBuf = array();
|
|
|
|
for ($i=0; $i<8; $i++)
|
|
{
|
|
// $sBuf[$i] = $sPinBuf[$i] ^ $sPanBuf[$i]; //十进制
|
|
// $sBuf[$i] = vsprintf("%02X", ($sPinBuf[$i] ^ $sPanBuf[$i]));
|
|
$sBuf[$i] = vsprintf("%c", ($sPinBuf[$i] ^ $sPanBuf[$i]));
|
|
}
|
|
unset($sPinBuf);
|
|
unset($sPanBuf);
|
|
// return $sBuf;
|
|
$sOutput = implode("", $sBuf); //数组转换为字符串
|
|
return $sOutput;
|
|
}
|
|
|