最近在使用PHP对接许多供应商的接口,各种各样的语言各种格式要求的接口都有,涉及到数据的 MD5加密,sha1 加密,sha256加密、解密、签名验证等各种问题。对于开发者来说需要深入理解HTTP协议的各个数据参数的含义。
网络协议
1、请求使用http协议,GET请求方式。注:请求如果涉及中文或者特殊字符,请做utf-8 进行urlencode编码。
2、返回格式为默认为xml,如果http请求返回500错误,务必在请求头Accept加上application/xml;
如需返回json格式,请把http 请求头中的Accept 改为 application/json;charset=UTF-8。
Content-Type: text/plain;
Content-Type: application/json; charset=utf-8;
Content-Type: application/x-www-form-urlencoded;
php rsa2解密,PHP RSA2 加密 、 解密 、签名 、验证签名
-------------------------------------------------------------------------------------------------------
RSA2 标准算法名称 SHA256WithRSA
1、RSA非对称加密技术
2、SHA256 是SHA-2下细分出的一种算法
SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发,属于SHA算法之一,是SHA-1的后继者。
详细介绍连接:https://blog.csdn.net/u011583927/article/details/80905740
1、加密和解密
公钥是公开的密钥,有加密方使用。只用于加密无法解密。私钥是不公开的,别人无法获取,用户解密。
注意的是,为什么私钥对同一数据进行签名加密的结果是一样的,使用公钥进行加密就不一样了呢?
详细请参考:https://blog.csdn.net/guyongqiangx/article/details/74930951
2、签名和验证签名
签名是由发送数据的一方发起的,防止传输过程中被篡改数据内容。因此签名使用的是私钥。而验证签名使用的是公钥。
附带:
java RSA2 加密、解密 、签名和验证签名 https://blog.csdn.net/TaLinBoy/article/details/106124535
IOS:RSA2 加密、解密 、签名和验证签名 https://blog.csdn.net/TaLinBoy/article/details/106140526
/** POST原始数据请求(Json) */
function sendPostRaw($url,$dataString,$headers=[]){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>$dataString,
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json; charset=utf-8', //Content-Type: text/plain
'Content-Length: '.strlen($dataString),
'businessId: '.$headers['businessId'],
'nonce: '.$headers['nonce'],
'timestamp: '.$headers['timestamp'],
'signType: '.$headers['signType'],
'sign: '.$headers['sign'],
),
));
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
/** post提交数据
* @param string $url 请求Url
* @param array $datas 提交的数据
* @return String
*/
private function sendPost($url, $params,$isPost = 1,$https = 0,$isJson = 0)
{
$httpInfo = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_USERAGENT,
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($https) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
}
if ($isPost) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, $url);
} else {
if ($params) {
if (is_array($params)) {
$params = http_build_query($params);
}
curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
} else {
curl_setopt($ch, CURLOPT_URL, $url);
}
}
if ($isJson) {
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
"Accept: application/x-www-form-urlencoded",
'Cache-Control: no-cache',
'Pragma: no-cache'
));
}
$response = curl_exec($ch);
if ($response === false) {
return false;
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$httpInfo = array_merge($httpInfo, curl_getinfo($ch));
curl_close($ch);
return $response;
}
/** RSA签名(空字符串参与签名)
* $post = array_filter($post); //参数值为空的,不参与签名
*/
private function rsaSign($params)
{
//1.ASCII码(字典序-升序)排序
ksort($params);
//2.拼接成字符串string
$string = '';
foreach ($params as $key => $v) {
$string .= (string)($key . '=' . $v . '&');
}
//3.拼接得到signTemp字符串
$signTemp = $string . 'MerchantKey=' . $this->key;
//4.获取RSA私钥信息
$absPath = dirname(__FILE__) . './../../config/ssl/renyue_rsa_private_key.pem'; //(正式私钥)
if($this->environment=='test'){
$absPath = dirname(__FILE__) . './../../config/ssl/renyue_rsa_private_key_test.pem'; //(测试私钥)
}
$content = file_get_contents($absPath);
$sContent = openssl_pkey_get_private($content);
//5.PHP-SHA256WithRSA 签名算法加密
openssl_sign($signTemp, $signature, $sContent, "SHA256");
//6.base64转换,得到SignSecret值
return base64_encode($signature);
}
/** 接口回执解密
* $returnSign = "Ho04NoxgWlRxvJ4CfUpBXplnmW8plaDK12i3V%2BeQI%2FdP92GtFTH4XJlSS60gk%2FGrm4IwfhwNqriADdOgJ1DajzEeTUvv3XodvIPrT1EMeIgUiu1aF0n%2F4U1W%2FcaMxfMORL8SVT7nhZtOzgluPYxT7oW8HZpwzYrZ%2BzANf6Loco0Ze%2BOQdf5VpaphwwGUUJWv5XqQTMR8UJ2HJSA4zMRFO2UIAW%2BM6JoOMJCG2bse6X2C%2Bd4On%2BySpCMJSby%2BfSMOSKD%2F3R520WJuYTfosVCb5PB5g2Lo0%2BZa%2BRG65vdwTn6%2BkfdzmanqPAu0AkZKFdO0jTRnhqYjGi1uuIu7ZjSJUw%3D%3D";
* 解密成功示例:string(148) "OrderNo=202406281034531358853&RechargeAccount=18857850025x&RechargeStatus=3&StoreNo=2024062810345442728&MerchantKey=3A765ADA5DAFE68FE2C6637ABB037ACB"
*/
public function getReceiptDecryptionInfo($returnSign='')
{
//1.获取签名回执
//$returnSign = urldecode($returnSign);
//2.获取RSA私钥信息
$absPath = dirname(__FILE__) . '/./../../config/ssl/renyue_rsa_private_key.pem'; //(正式私钥)
if($this->environment=='test'){
$absPath = dirname(__FILE__) . '/./../../config/ssl/renyue_rsa_private_key_test.pem'; //(测试私钥)
}
$content = file_get_contents($absPath);
$sContent = openssl_pkey_get_private($content);
//3.解密数据信息
openssl_private_decrypt(base64_decode($returnSign), $decrypted, $sContent);
//4.返回解密数据
return $decrypted;
}
sha1 加密(长度40字节)
--------------------------------------------------------------
$str = '203fpid';
$sha1 = sha1($str);
echo $sha1.'<br>';
php sha256加密 (长度64)
--------------------------------------------------------------
$str = '203fpidf02lvj!!_@#_!';
$sha256 = hash('sha256',$str);
echo $sha256.'<br>';
/** 生成签名(哈希sha256 64位)
* @param $data
* @return false|string
*/
public function _sign($data){
$data = array_filter($data);
ksort($data);
$temps = [];
foreach ($data as $key => $value) {
$temps[] = sprintf('%s=%s', $key, $value);
}
$signBefore = $this->app_secret.implode('&', $temps);
return hash('sha256',$signBefore);
}