PHPRSA签名(公钥、私钥)
签名算法:
Setp.1 确定待签名参数
在请求参数列表中,除去sign参数外,其他需要使⽤到的参数皆是要签名的参数。
在通知返回参数列表中,除去sign参数外,凡是通知返回回来的参数皆是要签名的参数。
Setp.2 对参数进⾏排序
对于待签名的所有参数,需要根据参数名⾸字符字典顺序(ascii值⼤⼩)排序,若遇到相同⾸字符,则判断第⼆个字符,以此类推。
Setp.3 ⽣成待签名字符串
将排序后的待签名参数以“&“符号拼接,形如:“参数名1=参数值1&参数名2=参数值2&….&参数名N=参数值N”。
Setp.4 ⽣成签名/验证签名
⽣成签名:把待签名字符串与商户的私钥⼀同放⼊RSA的签名函数中进⾏签名运算,从⽽得到签名结果字符串(sign值)。
验证签名:把待签名字符串、平台提供的公钥、通知返回参数中的参数sign值三者⼀同放⼊RSA的签名函数中进⾏签名运算,来判断签名是否验证通过。
1、公钥、私钥格式化(加上前后戳、每64位进⾏换⾏)
/**********************************私钥格式化*************************************/
1function formatPriKey($priKey) {
2$fKey = "-----BEGIN PRIVATE KEY-----\n";
3$len = strlen($priKey);
4for($i = 0; $i < $len; ) {
5$fKey = $fKey . substr($priKey, $i, 64) . "\n";
6$i += 64;
7    }
8$fKey .= "-----END PRIVATE KEY-----";
9return$fKey;
10 }
/**********************************公钥格式化*************************************/
1function formatPubKey($pubKey) {
2$fKey = "-----BEGIN PUBLIC KEY-----\n";
3$len = strlen($pubKey);
4for($i = 0; $i < $len; ) {
5$fKey = $fKey . substr($pubKey, $i, 64) . "\n";
6$i += 64;
7    }
8$fKey .= "-----END PUBLIC KEY-----";
9return$fKey;
10 }
2、私钥签名、公钥验签
/**********************************私钥签名*************************************/
1/**
2 * ⽣成签名
3 * @param    string    $signString 待签名字符串
4 * @param    [type]    $priKey    私钥
5 * @return  string    base64结果值
6*/
7function getSign($signString,$priKey){
8$privKeyId = openssl_pkey_get_private($priKey);
9$signature = '';
10    openssl_sign($signString, $signature, $privKeyId);
11    openssl_free_key($privKeyId);
12return base64_encode($signature);
13 }
/**********************************公钥验签*************************************/
1/**
2 * 校验签名
3 * @param    string    $pubKey 公钥
4 * @param    string    $sign  签名
5 * @param    string    $toSign 待签名字符串
6 * @param    string    $signature_alg 签名⽅式⽐如 sha1WithRSAEncryption 或者sha512
7 * @return  bool
8*/
9function checkSign($pubKey,$sign,$toSign,$signature_alg=OPENSSL_ALGO_SHA1){
10$publicKeyId = openssl_pkey_get_public($pubKey);
11$result = openssl_verify($toSign, base64_decode($sign), $publicKeyId,$signature_alg);
12    openssl_free_key($publicKeyId);
13return$result === 1 ? true : false;
14 }
3、公钥加密、私钥解密
/**********************************公钥加密*************************************/
1/**
2 *公钥加密
3  *@param    string    $sign_str  待加密字符串
4  *@param    string    $public_key  公钥
5  *@param    string    $signature_alg 加密⽅式
6  *@return    string
7*/
8function get_public_sign($sign_str,$public_key,$signature_alg=OPENSSL_ALGO_SHA1){
9$public_key = openssl_pkey_get_public($public_key);//加载密钥
10      openssl_sign($sign_str,$signature,$public_key,$signature_alg);//⽣成签名
11$signature = base64_encode($signature);
12    openssl_free_key($public);
13return$signature;
14  }
/**********************************私钥解密**************************************/
1  /**
php实例代码解密
2  *私钥解密
3  *@param    string    $sign_str  待加密字符串
4  *@param    string    $sign sign
5  *@param    string    $private_key 私钥
6  *@param    string    $signature_alg 加密⽅式
7  *@return    bool
8 */
9
10  function private_verify($sign_str,$sign,$private_key,$signature_alg=OPENSSL_ALGO_SHA1){
11    $private_key = openssl_get_privatekey($private_key);
12    $verify = openssl_verify($sign_str, base64_decode($sign), $private_key, $signature_alg);
13    openssl_free_key($private_key);
14    return$verify==1;//false or true
15 }
⽰例代码如下(私钥签名公钥验签):
<?php
$pubKey = '-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDr6H/ictALLsV9/63lPFSYDPQK
gRwEM2FiewfR/BYaPGfpgdl8lelNYqFxnqBRKbGnbFOwOxOu7oiiPYaJxcSU94hI
d3S0/UsSXyRfTaHT8ZZv+5luikQAG62hwkxqcSdL3aEMbqsHRfQ9RXiFAneiJJwZ
1D0nHPANfBA4UN+OXQIDAQAB
-----END PUBLIC KEY-----';
$priKey = '-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOvof+Jy0AsuxX3/
reU8VJgM9AqBHAQzYWJ7B9H8Fho8Z+mB2XyV6U1ioXGeoFEpsadsU7A7E67uiKI9
honFxJT3iEh3dLT9SxJfJF9NodPxlm/7mW6KRAAbraHCTGpxJ0vdoQxuqwdF9D1F
eIUCd6IknBnUPScc8A18EDhQ345dAgMBAAECgYEAoNlVIQShn45TcBa97dhV4Zqr
ZuIjRSX3V5uFeIKGW3smastzjAP3ICGI7Jx4uP5RuFMfOMD/Kb5QgTasHhIvdwe0
kuMdUqd8YCLgZaV1u02GWkp5I7bG2HRKAqfrpaExeOJt3Iqmggt208P3BNQLTOa2
NFtNqT+onI1dGwbC120CQQD2BbkrXPv+wGAKkcqIK77Bkrwpg7Iqj91uyVHBAleW
AgfWDFA3rJb8jDCARHte2ehMImmhbsQmVBjdI1DNdYWLAkEA9XnEoVVIL5IA09s0
XtL/Na065loDTJsQZiumdi6VMn6zWafu6GFhS0w5DQdkjtA7qhwpftjVRaWtK0DX
4qpItwJAKxGrbfT0RI/HAHKvYxFNbrPSbu4YNa1D1Y422rQfQyqN1qIHNQfo0sN0
BjB27I73RMTNey5Z9l/IjoYNMjq9qwJABChZ0jm1jUi1xuDRlEGSnQAgHUKtB6Eg
t/pJSXskf8RxmTUk8L6lfTb/SF81rs2MFSeA9GsLwbA6rJ7eiTJFJQJBAJnixcdp
F6knRxyOUDhWoa8uYmnUdcyrfo4dnNyliJbNTTSw0LJAGZsCbo9EDqQIxDrqDa9X
qj0yz6UT1JM37Tk=
-----END PRIVATE KEY-----';
//$priKey = formatPriKey($priKey);
//$pubKey = formatPubKey($pubKey);
$params = [
"merchant_id"=>"1",
"uid"=>"2122334455",
"out_trade_id"=>"134********",
"amount"=>"88",
"subject"=>"活动红包"
];
/
/获取预处理字符串
$signString = getSignString($params);
//预处理字符串为
//amount=88&merchant_id=1&out_trade_id=134********&subject=活动红包&uid=2122334455
//获取签名
$sign = getSign($signString,$priKey);
//⽣成的签名为
//k8DMuhe+q9rDVDgzAk8lFQEE+tZAahXLiZWExmiYl83vJpZlnKTBghLd1DM8itNzw3JYGhxR8ueHCIkkGyVh0BiPuKYmXFyrCwLVif9sMWCu2DFoEDFARZClDRCfE5rV+IDmumCBfVyxFY/uW/DIMS7AO7GlrydW5aVZ6xYKtBw= //验证签名
$res = checkSign($pubKey,$sign,$signString);
var_dump($res);//结果为 true
/**
* ⽣成签名
* @param    string    $signString 待签名字符串
* @param    [type]    $priKey    私钥
* @return  string    base64结果值
*/
function getSign($signString,$priKey){
$privKeyId = openssl_pkey_get_private($priKey);
$signature = '';
openssl_sign($signString, $signature, $privKeyId);
openssl_free_key($privKeyId);
return base64_encode($signature);
}
/**
* 校验签名
* @param    string    $pubKey 公钥
* @param    string    $sign  签名
* @param    string    $toSign 待签名字符串
* @param    string    $signature_alg 签名⽅式⽐如 sha1WithRSAEncryption 或者sha512
* @return  bool
*/
function checkSign($pubKey,$sign,$toSign,$signature_alg=OPENSSL_ALGO_SHA1){
$publicKeyId = openssl_pkey_get_public($pubKey);
$result = openssl_verify($toSign, base64_decode($sign), $publicKeyId,$signature_alg);
openssl_free_key($publicKeyId);
return$result === 1 ? true : false;
}
/**
* 获取待签名字符串
* @param    array    $params 参数数组
* @return  string
*/
function getSignString($params){
unset($params['sign']);
ksort($params);
reset($params);
$pairs = array();
foreach ($params as$k => $v) {
if(!empty($v)){
$pairs[] = "$k=$v";
}
}
return implode('&', $pairs);
}
/**
* 格式化私钥
*/
function formatPriKey($priKey) {
$fKey = "-----BEGIN PRIVATE KEY-----\n"; $len = strlen($priKey);
for($i = 0; $i < $len; ) {
$fKey = $fKey . substr($priKey, $i, 64) . "\n";
$i += 64;
}
$fKey .= "-----END PRIVATE KEY-----";
return$fKey;
}
/
**
* 格式化公钥
*/
function formatPubKey($pubKey) {
$fKey = "-----BEGIN PUBLIC KEY-----\n";
$len = strlen($pubKey);
for($i = 0; $i < $len; ) {
$fKey = $fKey . substr($pubKey, $i, 64) . "\n";
$i += 64;
}
$fKey .= "-----END PUBLIC KEY-----";
return$fKey;
}
>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。