>>>>>> 386b37d33e5ba817cba00df29efaefbd692e4dd1
class Gmdemo extends Controller{
//以下参数都需要金融云提供
//AES偏移量
protected $iv = 'abcdefghABCDEFGH';
<<<<<<< HEAD
protected $appID = "93f1a51c1-39d4-48e1-8119-a37b63c0ed8c";
protected $appSecretKey = "66a81e7a-dea3-4870-9c63-58712e13aa9b";
protected $tokenUrl = "https://mouldai.com/apiSIT/tzyj/approveDev";//回归环境
protected $token;
//合作机构自有公钥
const PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE6mJz31IQpqtv42a67pfUe6q6UKUa/Lxf2rzJC4iAK0p3dOooG/d+N2fs6qmzK+7smovqcP7VhA8D+OIvaVjMsw==";
=======
protected $appID = "96c8268e-cfa4-497f-9329-a5e3417f0825";
protected $appSecretKey = "921b3c06-eaed-7b1c-e053-010000717745";
protected $tokenUrl = "https://mouldai.com/apiSIT/tzyj/approveDev";//回归环境
protected $token;
//合作机构自有公钥
const PUBLIC_KEY = "DE3w4DgjV+np0oHQzSDUgvlxGKPhi/gHBRp8dtjun+z6uqrRJE6B1qswZpaSCs3tp0tm98ZjjL9RTuNh4dyUuA==";
>>>>>>> 386b37d33e5ba817cba00df29efaefbd692e4dd1
//合作机构自有私钥
const PRIVATE_KEY = "778NKKZgdS9IGm/crvajNPoq5CHJNEKXptciF/1SU3I=";
//泰隆银行公钥
const CGB_PUBLIC_KEY = "kZYtvaa+HIImu0xhONxte8wyXmMBe7HKKf1i1fqU7Wf8PrsmvAguPNClPXfOoxqW8gmy5qrFK9oX3tvmrq4r0A==";
public function _initialize()
{
// 初始化加密扩展
echo "--------php_crypto_init 初始化开始--------\n";
<<<<<<< HEAD
$path = "/www/wwwroot/hgd.liuniu946.com/public/opt/php/libcryptAPIsm_lnx64.so";//国密动态库路径
=======
$path = "/opt/php/libcryptAPIsm_lnx64.so";
>>>>>>> 386b37d33e5ba817cba00df29efaefbd692e4dd1
php_crypto_init($path);
echo "--------php_crypto_init 初始化结束-------\n";
}
function string2hex($string){
$hex = '';
for($i = 0;$i < strlen($string); $i++){
$ch = dechex(ord($string[$i]));
if(strlen($ch)==1){
$ch = "0".$ch;
}
$hex .=$ch;
}
return $hex;
}
//获取token
public function getToken(){
//获取6位数字符串
$seqNO = (string)rand(100000,999999);
//获取16位随机字符串并md5 转大写 得到
$key = strtoupper(md5($this->getKey()));
//echo $this->string2hex(base64_decode(self::PRIVATE_KEY));
echo $this->string2hex(base64_decode(self::PUBLIC_KEY));
//初始化转换密钥信息
<<<<<<< HEAD
// php_HextoAsc($this->string2hex(base64_decode(self::PRIVATE_KEY)),$k1);
// php_HextoAsc($this->string2hex(base64_decode(self::PUBLIC_KEY)),$k2);
// php_HextoAsc($this->string2hex(base64_decode(self::CGB_PUBLIC_KEY)),$gf_k);
$this->string2hex(base64_decode(self::PRIVATE_KEY));
$this->string2hex(base64_decode(self::PUBLIC_KEY));
$this->string2hex(base64_decode(self::CGB_PUBLIC_KEY));
=======
php_HextoAsc($this->string2hex(base64_decode(self::PRIVATE_KEY)),$k1);
php_HextoAsc($this->string2hex(base64_decode(self::PUBLIC_KEY)),$k2);
php_HextoAsc($this->string2hex(base64_decode(self::CGB_PUBLIC_KEY)),$gf_k);
>>>>>>> 386b37d33e5ba817cba00df29efaefbd692e4dd1
//拼接参数数组
$data = [
'appID' => $this->appID,
'seqNO' => $seqNO,
'random'=> strtoupper(md5($seqNO)),
'sm2EncryptData' => $this->SM2Encrypt($key,$gf_k), //sm2加密key
'sm2Sign' => $this->SM2Sign($key,$k2,$k1), //sm2加密key
];
//拼接签名参数,md5转大写
$data['sign'] = $this->SM3Crypt($data['random'] . $data['seqNO'] . $this->appSecretKey . $key);
//发送post接口请求
$res = $this->https_post($this->tokenUrl,$data);
//解密返回token数据
$token = $this->SM2Decrypt(base64_decode($res['sm2EncryptData']),$k1);
$this->token = $token;
//返回token
return $token;
}
//业务请求数据
public function postJry()
{
//创建模拟请求数据,必须包含head,body
$data = [
'head' => [
'id' => 8989
],
'body' => [
'code'=>"000000",
'msg'=>"测试请求"
]
];
$res = $this->scanPaymentCode($data);
dump("返回结果");
halt($res);
}
//业务请求封装
public function scanPaymentCode($array=[])
{
<<<<<<< HEAD
$k1 = self::PUBLIC_KEY;
$k2 = self::PRIVATE_KEY;
$gf_k = self::CGB_PUBLIC_KEY;
//初始化转换密钥信息
// php_HextoAsc($this->string2hex(base64_decode(self::PRIVATE_KEY)),$k1);
// php_HextoAsc($this->string2hex(base64_decode(self::PUBLIC_KEY)),$k2);
// php_HextoAsc($this->string2hex(base64_decode(self::CGB_PUBLIC_KEY)),$gf_k);
$this->string2hex(base64_decode(self::PRIVATE_KEY));
$this->string2hex(base64_decode(self::PUBLIC_KEY));
$this->string2hex(base64_decode(self::CGB_PUBLIC_KEY));
//数据转json
=======
//初始化转换密钥信息
php_HextoAsc($this->string2hex(base64_decode(self::PRIVATE_KEY)),$k1);
php_HextoAsc($this->string2hex(base64_decode(self::PUBLIC_KEY)),$k2);
php_HextoAsc($this->string2hex(base64_decode(self::CGB_PUBLIC_KEY)),$gf_k);
// $this->string2hex(base64_decode(self::PRIVATE_KEY));
// $this->string2hex(base64_decode(self::PUBLIC_KEY));
// $this->string2hex(base64_decode(self::CGB_PUBLIC_KEY));
//数据转json
>>>>>>> 386b37d33e5ba817cba00df29efaefbd692e4dd1
$json = json_encode($array, JSON_UNESCAPED_UNICODE);
//获取随机6位字符串数字
$seqNO = (string)rand(100000,999999);
//获取随机字符串秘钥,md5 并转大写
$key = strtoupper(md5($this->getKey()));
//拼接请求数据
$data = [
'appID' => $this->appID,
'seqNO' => $seqNO,
'signMethod' => "SM3",
'encryptMethod' => "SM4",
'appAccessToken'=> $this->getToken(),//获取token
<<<<<<< HEAD
'sm2EncryptData' => $this->SM2Encrypt($key,self::PUBLIC_KEY), //sm2加密key
'sm2Sign' => $this->SM2Sign($key,$k2,$k1), //sm2加密key
];
=======
'sm2EncryptData' => $this->SM2Encrypt($key,$gf_k), //sm2加密key
'sm2Sign' => $this->SM2Sign($key,$k2,$k1), //sm2加密key
];
>>>>>>> 386b37d33e5ba817cba00df29efaefbd692e4dd1
//拼接签名参数,md5转大写
$data['sign'] = $this->SM3Crypt($json . $data['seqNO'] . $this->appSecretKey . $key);
//AES加密业务数据
$data['reqData'] = $this->SM4Encrypt($json,$data['seqNO'] . $data['appAccessToken'] . $this->appSecretKey . $key);
dump("业务数据json");
dump($json);
dump("请求数据");
dump($data);
$res = $this->https_post("https://mouldai.com/apiSIT/tzyj/scanPaymentCode",$data);
//解密sm2密钥
$sm2Key = $this->SM2Decrypt(base64_decode($res['sm2EncryptData']),$k1);
dump("sm2解密数据:".$sm2Key);
//SM4解密数据
$rspData = $this->SM4Decrypt($res['rspData'],$res['seqNO'] .$data['appAccessToken']. $this->appSecretKey. $sm2Key);
dump("sm4解密报文数据:".$rspData);
//sm3验签数据校验
$sm3SignData = $this->SM3Crypt($rspData . $res['seqNO'] .$this->appSecretKey . $sm2Key);
dump("sm3响应报文拼接加签:".$sm3SignData);
$signData = $res['sign'];
dump("sm3响应报文签名:".$signData);
if ($sm3SignData == $signData) {
dump("验签成功!");
}
dump($res);
return $res;
}
//获取post数据并解密解签获得业务数据
public function getPostData()
{
//获取post数据
$arr = input("post.");
//模拟post获取数据
$arr = '{"sign":"1CA0926A5C8BC2E2347E57016650E731","signMethod":"MD5","rsaEncryptData":"xs8lNVCj4ZCsAbXoJHI+AmRPqDJk01dlt3q7Jb9Vox4SNvvx6F+DclM2v1FdnDxAsNgXBERLXCc3SOFnqtrcMdYxc2GKyF+YTLJKjX0NmlGkXlO2oipIzhIL94la\/NGEzlT+JL4I8KF5vZvE+4gudkg0mZ+jC6jPWc+qyM6RROdwbgYPCiOpVTaQ+jtIxwz4rCY\/a2z\/fAFazzApUbyRxsCTVRESJ+3dU8V9zYxE7VzrV+IlOCwJdAIAfGPcwjq5wd3p\/3yEeFDBbZz0N6jnIEIlkCH99NsNFWIYY2mH0K2z+ccpJlBejoNq+FaxusS2DvZfJhp8xa3dav8itVyiSw==","encryptMethod":"AES","reqData":"QbYx9PwqKwy30K1SSgiorq9Sg9taSxImEw6qwY93N0QhsRb1UHqBghS+WmbBRZxrBTCMYNGBsG1GFvUdJxIrdXaQ4qBU\/PTpIjLlD+bvRyE27OYgHrSpQ6umylxWXSTYUIO0qbdTjNTR8UwRKPlHjuUJ149E5eH+s\/oyE6zZi9KNzx8BwjeZ\/Qeo\/CQF7fMuu3uJF7XOOIDqLidXvevQEr8hHLUyT40a\/NZsOAoqQSoNppazy+tDuttATH7gFWjFKNzRtt89wDdbjWNtK95tc\/uUBojfjg5HKcctSmqQ7jW6HvA2J5k3WnC6mxsTdaU9WPjtKbnqGUTkoM9YbJs1VghcnnQLSH49wAY7kB5SwWwTaPkHZy5kvytfMvLjwgjUioW0qYSpZyaBww4dSXJ0bQ1Mb+TArunrCpIzl2T4ZkzWT3\/j0m4bJoq7le4l03NVAn8iA3ju2asrBbrySTWzQ9vXDQbq1q+S5uh9YTXrVq0dM6CMNV8KquOCEC0UyaTKxCK2+cAS9LDQD4APXRTuNhkR57LKox2CfvN+CTDlWw8QfFfYKdNpmt\/OHklrUez0LcfMluc08ce1fvoDCuOqMN51y5qhV+d3utWa5rBjvzhE8de5qi54l3qW4EV03sQRdvN7R433fxOVt33N1mZ3NOwx1xjnJ4ivdVuhZ1XbGHd\/B7NGGafQbx3RChEIT250Kl3vih\/P2yF1ozQC8MY6sAHgOxAufmos8DoOwwWy9L59lNqN2sAnVpPalvjM4UCa8pkSrToDaoU4Sc44JOBghQ==","appAccessToken":"","seqNO":"127600","appID":"a539d3d7-3d4b-454b-9c49-7fb83fb8b611"}';//正式获取数据删除这里
$arr = json_decode($arr, true); //正式获取数据删除这里
//检验字段是否缺失
if (!isset($arr['rsaEncryptData']) || !isset($arr['seqNO']) || !isset($arr['signMethod']) || !isset($arr['sign']) || !isset($arr['encryptMethod']) || !isset($arr['reqData']) || !isset($arr['appID'])) {
return $this->runJson("1000001", "缺少参数");
}
dump("获取到的post数据");
dump($arr);
//rsa解密秘钥字段rsaEncryptData
$rasKey = $this->decryptByPublicKey($arr['rsaEncryptData']);
dump("解密后的秘钥");
dump($rasKey);
//拼接秘钥
$key = $arr['seqNO'] . $this->token . $this->appSecretKey . $rasKey;
//秘钥转md5 转大写
$key = strtoupper(md5($key));
//aes解密
$res = $this->decrypt($arr['reqData'], $key);
$res = json_decode($res, true);
dump("数据结果");
halt($res);
}
//SM2Encrypt
function SM2Encrypt($data,$pubkey){
//sm2加密
$recode = php_SM2Encrypt($data, $cipher, $pubkey);
echo "
recode:$recode \n";
//php_SM2Encrypt接口返回的密文值是c1c3c2格式,以下示例转DER编码
$recode = php_SM2FormatConvert(102,$cipher, $der);
echo "
recode:$recode \n";
//SM2加密字符串转base64编码
$sm2encrypted = base64_encode($der);
echo "
sm2加密字符串base64:$sm2encrypted \n";
return $sm2encrypted;
}
//SM2Decrypt
function SM2Decrypt($data,$privkey){
//php_SM2Decrypt 接收密文值是c1c3c2格式,若对方给的密文值是DER格式 则通过如下方式转换,然后再传入接口解密
$recode = php_SM2FormatConvert(101,$data,$c1c3c2);
echo "
recode:$recode \n";
//解密
$recode = php_SM2Decrypt($c1c3c2,$plain,$privkey);
echo "
recode:$recode \n";
echo "
解密数据plain: $plain\n";
return $plain;
}
//SM2Sign
function SM2Sign($data,$pubkey,$privkey){
//签名
$recode = php_SM2Sign($data, $redata,$privkey,$pubkey);
echo "
recode:$recode \n";
//php_SM2Sign接口返回的签名值是RS格式,以下示例转DER编码
$php_func = 'php_SM2FormatConvert';
$recode = $php_func(202,$redata, $der);
echo "
recode:$recode \n";
echo "
data: ".$data." len:".strlen($data)." \n";
echo "
signValue DER: ".base64_encode($der)." len:".strlen($der)." \n";
//加签数据base64返回
$sm2SignData = base64_encode($der);
return $sm2SignData;
}
//SM3Crypt
function SM3Crypt($data){
$recode = php_SM3Crypt($data,$sm3hash);
echo "
recode:$recode \n";
//加签数据base64返回
return strtoupper($this->string2hex($sm3hash));
}
//16进制转换为二进制
function hex2String($hexdata){
$bindata="";
for ($i=0;$i < strlen($hexdata);$i+=2) {
$bindata.=chr(hexdec(substr($hexdata,$i,2)));
}
return $bindata;
}
//SM4Encrypt
function SM4Encrypt($data,$password){
//加密密码做特殊处理 先MD5转换大写 从第8位开始截取16个字符串
$password = substr(strtoupper(md5($password)),8,16);
echo "
【SM4】MD5加密密码=======".$password;
//接口是密文key,将明文key加密后再传入php_SM4CBCCrypt进行数据加密
//不必要每次都加密key,建议手工加密一次,将key密文保存使用,key明文保存至安全的地方
//若是会话级别的key则自行定策略
$recode = php_CryptKey(0, $password,$key);
echo "
recode:$recode \n";
//加密
$recode = php_SM4CBCCrypt(0,$data,$redata,$key,$this->iv);
echo "
recode:$recode \n";
echo "
redata: ".base64_encode($redata)." \n";
$SM4Encryptdata = base64_encode($redata);
return $SM4Encryptdata;
}
//SM4Encrypt
function SM4Decrypt($data,$password){
echo "
SM4解密数据=======".$data;
//加密密码做特殊处理
$password = substr(strtoupper(md5($password)),8,16);
echo "
MD5密码=======".$password;
//接口是密文key,将明文key加密后再传入php_SM4CBCCrypt进行数据加密
//不必要每次都加密key,建议手工加密一次,将key密文保存使用,key明文保存至安全的地方
//若是会话级别的key则自行定策略
$recode = php_CryptKey(0, $password,$key);
echo "
recode:$recode \n";
//解密
$recode = php_SM4CBCCrypt(1,base64_decode($data),$dedata,$key,$this->iv);
echo "
sm4[解密]recode:$recode \n";
return $dedata;
}
/**
* 公钥解密
* @param 密文数据 $data
* @return 原文结果 string
*/
private function decryptByPublicKey($data) {
$data = base64_decode($data);
openssl_public_decrypt($data,$decrypted,$this->publicKey,OPENSSL_PKCS1_PADDING);//公钥解密
return $decrypted;
}
/**
* 私钥加密
* @param 原始数据 $data
* @return 密文结果 string
*/
private function encryptByPrivateKey($data) {
openssl_private_encrypt($data,$encrypted,$this->privateKey,OPENSSL_PKCS1_PADDING);//私钥加密
$encrypted = base64_encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
return $encrypted;
}
//封装返回数据
private function runJson($code="000000",$msg="完成"){
return json(['code'=>$code,'message'=>$msg]);
//以下加密信息返回,暂时不用使用
// $data = [
// 'signMethod' => 'MD5',
// 'encryptMethod' => 'AES',
// 'appID' => $this->appID,
// 'seqNO' => (string)rand(100000,999999),
// 'appAccessToken' => ''
// ];
// $json = json_encode(['code'=>$code, 'message'=>$msg]);
// $key = strtoupper(md5(getKey()));//随机秘钥
// $data['rsaEncryptData'] = $this->encryptByPrivateKey($key);
// $data['reqData'] = $this->encrypt($json, $key);
// $data['sign'] = strtoupper(md5($data['reqData'] . $data['seqNO'] . $this->appSecretKey . $key ));
// return json($data);
}
// curl post请求
private function https_post($url, $data = null)
{
$data = json_encode($data, JSON_UNESCAPED_SLASHES);
$header [] = 'Content-Type:application/x-www-form-urlencoded';
$ch = curl_init();
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $header );
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tmpInfo = curl_exec($ch);
curl_close($ch);
$tmpInfo1 = json_decode($tmpInfo, true);
return $tmpInfo1;
}
/**
* 获得随机字符串
**/
private function getKey($length = 16)
{
// 密码字符集,可任意添加你需要的字符
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ2345678';
$key = '';
for ($i = 0; $i < $length; $i++) {
// 这里提供两种字符获取方式
// 第一种是使用 substr 截取$chars中的任意一位字符;
// 第二种是取字符数组 $chars 的任意元素
// $key .= substr($chars, mt_rand(0, strlen($chars) – 1), 1);
$key .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $key;
}
}