PHP签名验签,解决中文字符验签失败的问题

<?php
/**
 * 生成签名前的字符串
 *
 * @param $params
 * @return string
 */
function getParamsString($params)
{
    if (!is_array($params))
        $params = array();
    ksort($params);
    $str = '';
    foreach ($params as $k => $v) {
        $str .= $v != ''?$k . $v:'';
    }
    return $str;
}
/**
 * 根据原文生成签名内容
 *
 * @param string $data 原文内容
 *
 * @return string
 */
function sign($data)
{
    $filePath = 'rsa_private_dev.pfx';
    if(!file_exists($filePath)) {
        return false;
    }
    $pkcs12 = file_get_contents($filePath);
    if (openssl_pkcs12_read($pkcs12, $certs, '123456')) {
        $privateKey = $certs['pkey']; //根据实际情况键值可能不同
        $binary_signature = "";
        if (openssl_sign(utf8_encode($data), $binarySignature, $privateKey, OPENSSL_ALGO_SHA1)) {
            return bin2hex($binarySignature);
        } else {
            return '';
        }
    } else {
        return '';
    }
}
/**
 * 验证签名自己生成的是否正确
 *
 * @param string $data 签名的原文
 * @param string $signature 签名
 *
 * @return bool
 */
function verifySign($data, $signature)
{
    $filePath = 'rsa_private_dev.pfx';
    if(!file_exists($filePath)) {
        return false;
    }

    $pkcs12 = file_get_contents($filePath);
    if (openssl_pkcs12_read($pkcs12, $certs, '123456')) {
        $publicKey = $certs['cert'];
        //需要使用utf8_encode(),否则中文字符验签失败
        $ok = openssl_verify(utf8_encode($data), hex2bin($signature), $publicKey);
        if ($ok == 1) {
            return true;
        }
    }
    return false;
}


$data = [
    'merNo'=>'10001000000089',
    'respCode'=>'FAN00012',
    'srcReqDate'=>20170705,
    'aa'=>'你好',
];
$data = getParamsString($data);

$sign_ret = sign($data);

var_dump($sign_ret);
echo PHP_EOL;
var_dump(verifySign($data, $sign_ret));

评论