You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
6.1 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
require_once("Base64Url.php");
require_once("AESEncrypter.php");
abstract class YopSignUtils{
/**
* 签名生成算法
* @param array $params API调用的请求参数集合的关联数组不包含sign参数
* @param array $ignoreParamNames 忽略的参数数组
* @param String $secret 密钥
* @param String $algName 加密算法
*
md2
md4
md5
sha1
sha256
sha384
sha512
ripemd128
ripemd160
ripemd256
ripemd320
whirlpool
*
* @return string 返回参数签名值
*/
static function sign($params, $ignoreParamNames='', $secret, $algName='sha256',$debug=false){
$str = ''; //待签名字符串
//先将参数以其参数名的字典序升序进行排序
$requestparams = $params;
ksort($requestparams);
//遍历排序后的参数数组中的每一个key/value对
foreach ($requestparams as $k => $v) {
//查看Key 是否为忽略参数
if(!in_array($k,$ignoreParamNames)){
//为key/value对生成一个keyvalue格式的字符串并拼接到待签名字符串后面
//value不为空,则进行加密
if (!($v === NULL)) {
$str .= "$k$v";
}
}
}
//将签名密钥拼接到签名字符串两头
$str = $secret.$str.$secret;
//通过指定算法生成sing
$signValue = hash($algName,$str);
if ($debug) {
print_r($YopConfig);
var_dump("algName=".$algName);
var_dump("str=".$str);
var_dump("signValue=".$signValue);
}
return $signValue;
}
/**
* 签名验证算法
* @param array $result API调用的请求参数集合的关联数组不包含sign参数
* @param String $secret 密钥
* @param String $algName 加密算法
* @param String $sign 签名值
* @return string 返回签名是否正确 0 - 如果两个字符串相等
*/
static function isValidResult($result, $secret, $algName,$sign){
// var_dump($result);
// $string=json_encode($result,true);
// $string=json_decode($string,true);
// var_dump($string);
$Str="";
foreach ($result as $k=>$v){
$Str .= strlen($Str) == 0 ? "" : "&";
$Str.=$k."=".$v;
}
$newString = $secret.$Str.$secret;
// echo $newString;
if(strcasecmp($sign,hash($algName,$newString))==0){
return true;
}else{
return false;
}
}
static function decrypt($source,$private_Key, $public_Key)
{
$private_key = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($private_Key, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
extension_loaded('openssl') or die('php需要openssl扩展支持');
/* 提取私钥 */
$privateKey = openssl_get_privatekey($private_key);
($privateKey) or die('密钥不可用');
//分解参数
$args = explode('$', $source);
if (count($args) != 4) {
die('source invalid : ');
}
$encryptedRandomKeyToBase64 = $args[0];
$encryptedDataToBase64 = $args[1];
$symmetricEncryptAlg = $args[2];
$digestAlg = $args[3];
//用私钥对随机密钥进行解密
openssl_private_decrypt(Base64Url::decode($encryptedRandomKeyToBase64), $randomKey, $privateKey);
openssl_free_key($privateKey);
$encryptedData = openssl_decrypt(Base64Url::decode($encryptedDataToBase64), "AES-128-ECB", $randomKey, OPENSSL_RAW_DATA);
//分解参数
$signToBase64=substr(strrchr($encryptedData,'$'),1);
$sourceData = substr($encryptedData,0,strlen($encryptedData)-strlen($signToBase64)-1);
$public_key = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($public_Key, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
$publicKey = openssl_pkey_get_public($public_key);
$res = openssl_verify($sourceData,Base64Url::decode($signToBase64), $publicKey,$digestAlg); //验证
openssl_free_key($publicKey);
//输出验证结果1验证成功0验证失败
if ($res == 1) {
return $sourceData;
} else {
Die("verifySign fail!");
}
}
static function signRsa($source,$private_Key)
{
$private_key = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($private_Key, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
extension_loaded('openssl') or die('php需要openssl扩展支持');
/* 提取私钥 */
$privateKey = openssl_get_privatekey($private_key);
($privateKey) or die('密钥不可用');
openssl_sign($source, $encode_data, $privateKey, "SHA256");
openssl_free_key($privateKey);
$signToBase64 = Base64Url::encode($encode_data);
$signToBase64 .= '$SHA256';
return $signToBase64;
}
static function getPrivateKey($filepath,$password)
{
//var_dump($filepath);
$pkcs12 = file_get_contents($filepath);
openssl_pkcs12_read($pkcs12, $certs, $password);
$prikeyid = $certs['pkey']; //私钥
$prikeyid = str_replace('-----BEGIN RSA PRIVATE KEY-----','',$prikeyid);
$prikeyid = str_replace('-----END RSA PRIVATE KEY-----','',$prikeyid);
$prikeyid = preg_replace("/(\r\n|\n|\r|\t)/i", '', $prikeyid);
return $prikeyid;
}
static function verifySign($source,$sign, $public_Key)
{
$content=strstr($source, '&sign', TRUE);
$public_key = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($public_Key, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
$publicKey = openssl_pkey_get_public($public_key);
$res = openssl_verify($content,Base64Url::decode($sign), $public_key,'SHA256'); //验证
openssl_free_key($publicKey);
//输出验证结果1验证成功0验证失败
if ($res == 1) {
return true;
} else {
Die("verifySign fail!");
}
}
}