签名算法:

   Setp.1 确定待签名参数

       在请求参数列表中,除去sign参数外,其他需要使用到的参数皆是要签名的参数。

在通知返回参数列表中,除去sign参数外,凡是通知返回回来的参数皆是要签名的参数。

Setp.2 对参数进行排序
       对于待签名的所有参数,需要根据参数名首字符字典顺序(ascii值大小)排序,若遇到相同首字符,则判断第二个字符,以此类推。

Setp.3 生成待签名字符串
        将排序后的待签名参数以“&“符号拼接, 形如:“参数名1=参数值1&参数名2=参数值2&….&参数名N=参数值N”。

Setp.4 生成签名/验证签名
        生成签名:把待签名字符串与商户的私钥一同放入RSA的签名函数中进行签名运算,从而得到签名结果字符串(sign值)。

验证签名:把待签名字符串、平台提供的公钥、通知返回参数中的参数sign值三者一同放入RSA的签名函数中进行签名运算,来判断签名是否验证通过。

1、公钥、私钥格式化(加上前后戳、每64位进行换行)

/**********************************私钥格式化*************************************/

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

2、私钥签名、公钥验签

/**********************************私钥签名*************************************/

 /**
* 生成签名
* @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;
}

3、公钥加密、私钥解密

/**********************************公钥加密*************************************/

 /**
*公钥加密
*@param string $sign_str 待加密字符串
*@param string $public_key 公钥
*@param string $signature_alg 加密方式
*@return string
*/
function get_public_sign($sign_str,$public_key,$signature_alg=OPENSSL_ALGO_SHA1){
$public_key = openssl_pkey_get_public($public_key);//加载密钥
openssl_sign($sign_str,$signature,$public_key,$signature_alg);//生成签名
$signature = base64_encode($signature);
openssl_free_key($public);
return $signature;
}

/**********************************私钥解密**************************************/

 1  /**
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"=>"13423423423",
"amount"=>"88",
"subject"=>"活动红包"
]; //获取预处理字符串
$signString = getSignString($params);
//预处理字符串为
//amount=88&merchant_id=1&out_trade_id=13423423423&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;
}
?>

PHP RSA签名(公钥、私钥)的更多相关文章

  1. python 加密 解密 签名 验证签名 公钥 私钥 非对称加密 RSA

    加密与解密,这很重要,我们已经可以用pypcap+npcap简单嗅探到网络中的数据包了.而这个工具其实可以嗅探到更多的数据.如果我们和别人之间传输的数据被别人嗅探到,那么信息泄漏,信息被篡改,将给我们 ...

  2. java RSA 生成公钥私钥

    /** * 引进的包都是Java自带的jar包 * 秘钥相关包 * base64 编解码 * 这里只用到了编码 */ import java.security.Key; import java.sec ...

  3. Java RSA 生成公钥 私钥

    目前为止,RSA是应用最多的公钥加密算法,能够抵抗已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准. RSA算法中,每个通信主体都有两个钥匙,一个公钥(Public Key)用来对数据进行加密 ...

  4. WP8.1 RSA 加解密实例(导入公钥私钥)

    因项目上需要用到,之前在WP8.0的环境上调试通过,现在在开发8.1时发现已不支持原来的加密库,所以无法使用以前的方法,不得已,去寻找windows命名空间下RSA的加解密方法,经过几天的尝试,将解决 ...

  5. C#.NET RSA 私钥签名 公钥验证签名

    C#.NET RSA 私钥签名 公钥验证签名 公钥验签 1.待签名字符串转为byte数组时,一般使用UTF8. 2.将私钥字符串(PKCS8或PKCS1格式)转为C#.NET的RSACryptoSer ...

  6. OpenSSL与公钥私钥证书签名的千丝万缕

    导语 人对任何事物的认识都是阶段性的,从无知到知晓,从懵懂到半知半解,从误解到将信将疑,从晕头转向到下定决心吃透. 介绍 OpenSSL是一个强大的命令行工具,它可以用来处理许多种跟PKI(Publi ...

  7. RSA的公钥、私钥

    一.举个例子 1.发消息 用对方的公钥给对方发消息 2.发公告 发公告的时候,用自己的私钥形成签名! 二.加密和签名 RSA的公钥.私钥是互相对应的,RSA会生成两个密钥,你可以把任何一个用于公钥,然 ...

  8. PHP中使用OpenSSL生成RSA公钥私钥及进行加密解密示例(非对称加密)

    php服务端与客户端交互.提供开放api时,通常需要对敏感的部分api数据传输进行数据加密,这时候rsa非对称加密就能派上用处了,下面通过一个例子来说明如何用php来实现数据的加密解密 先了解一下关于 ...

  9. rsa 公钥 私钥

    如果用于加密解密,那就是用公钥加密私钥解密(仅你可读但别人不可读,任何人都可写)如果用于证书验证,那就是用私钥加密公钥解密(仅你可写但别人不可写,任何人都可读) 最后,RSA的公钥.私钥是互相对应的. ...

随机推荐

  1. 爬虫2:html页面+beautifulsoap模块+post方式+demo

    爬取html页面,有时需要设置参数post方式请求,生成json,保存文件中. 1)引入模块 import requests from bs4 import BeautifulSoup url_ = ...

  2. HTML DIV充满整个屏幕

    <!DOCTYPE html> <html> <head> <title>A Little Game!</title> <meta c ...

  3. PMP(第六版)中的控制账户、规划包、工作包

    PMP(第六版)中的控制账户.规划包.工作包 控制账户是一个管理控制点,在该控制点上,把范围.预算和进度加以整合,并与挣值比较,以测量绩效.控制账户拥有2个或以上的工作包,但每个工作包只与一个控制账户 ...

  4. css 动画animation基本属性(干货)

    /* 动画名称 */ animation-name: cloud; /* 属性定义动画完成一个周期所需要的时间,以秒或毫秒计 */ animation-duration:1s; /* 属性定义动画何时 ...

  5. 12.Nginx代理与负载均衡

    1.什么是代理? 代为办理 --> 代理 2.Nginx正向代理.反向代理 正向代理: --> 上网 | 路由器替代 反向代理: --> 正向与反向代理的区别: 区别在于形式上服务的 ...

  6. IDEA+docker,进行远程漏洞调试(weblogic)

    用于学习java漏洞debug. 以weblogic为例. cve-2017-10271 weblogic:10.3.6 环境搭建 拿docker为例 https://github.com/vulhu ...

  7. 小白学 Python(11):基础数据结构(元组)

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  8. 实用脚本awk

    非常实用的awk 有时候需要去服务器下载几个日志 日志太多,翻滚起来很麻烦,操作又慢又复杂. 可以使用这个下载最新的两个文件 ls -lt | head -3 | awk -F ' ' '{if(NR ...

  9. mysql库表优化实例

    一.SQL优化 1.优化SQL一般步骤 1.1 查看SQL执行频率 SHOW STATUS LIKE 'Com_%'; Com_select:执行SELECT操作的次数,一次查询累加1.其他类似 以下 ...

  10. vue表单属性

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...