When Huawei SDK is accessed, all kinds of signatures are annoying. Official documents do not have detailed DEMO and debugging tools, so it is very difficult to debug. After stepping on many pits, it finally passed the verification.
1. Verify login signature
Parameters:
public function callGameLoginService(){
$apiParams['appId'] = $this->appId;
$apiParams['cpId'] = $this->cpId;
$apiParams['playerId'] = $this->playerId;
$apiParams['playerLevel'] = $this->playerLevel;
$apiParams['playerSSign'] = $this->playerSSign;
$apiParams['private_key'] = $this->private_key;
$apiParams['public_key'] = $this->public_key;
$apiParams['ts'] = $this->ts;
$apiParams['method'] = 'external.hms.gs.checkPlayerSign';
$url = 'https://gss-cn.game.hicloud.com/gameservice/api/gbClientApi';
//Constructing source strings
$key_string = $this->getSignContent($apiParams);
//Get signature
$apiParams['cpSign'] = $this->rsasign($key_string,$apiParams['private_key']);
Yii::error('tstststststststs+++++++++: : '.$apiParams['playerSSign']);
$resp = json_decode($this->curl($url, $apiParams),true);
if($resp['rtnCode'] == 0){
//Verify the signature and save the updated user information
}else {
return json_encode(['code'=>1,'msg'=>'Failed to verify signature!']);
}
}
a. Construct source string
protected function getSignContent($params) {
ksort($params);//Prioritize
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
// Convert to target character set
$v = urlencode($this->characet($v, "UTF-8"));//It's better to convert the code. Each parameter must be urlebcode
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
}
3lhbjayfd03rwb2xbrklnf7m455deu2bvpzosi7bhtdnpd0btxy7pwlaslcsx7c7wqhn4 / awxdiu + ki2ppbstusd ecoUQQATBU35bQE2V7DtOsoGAhseuKXZe7yExMqszyZHLKaaqsbqq1rCua6FvJtwlwO82eY7N5kyW29r3MQ/uW1XGh4aPDods9UfD90BSLoPPmLjV9tREX/HFIdxkZ3FVWbkcWR4YQ==
b. Construct signature
protected function sign($data, $cpAuthKey) {
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($cpAuthKey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
$sign = base64_encode($sign);
return $sign;
}
Note that if the private key participating in the signature is written in the configuration, it cannot be wrapped. It must be a complete line. Otherwise, an error will be reported. If the file is imported, it is unnecessary.
2, Construct sign of pay ment interface
Required parameters:
$apiParams = array(
'productName' => $prod->product_name,
'productDesc' => $prod->product_desc,
'merchantId' => $config['merchantId'],
'applicationID' => $config['appId'],
'amount' => sprintf('%.2f',$prod->price),
'requestId' => $model->orderid,
'country' => $config['country'],
'currency' => $config['currency'],
'sdkChannel' => $config['sdkChannel'],
'urlver' => '2',
'url' => $config['url']
);
The parameter values of these parameters must be exactly the same as those of the client.
a. Construct the source string. There are some differences between constructing the source string and logging in.
protected function getSignContent($params) {
ksort($params);//sort
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
// Convert to target character set
//$v = urlencode ($this - > characet ($V, "UTF-8"); no urlencode required
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
}
b, signature
protected function sign($data, $cpAuthKey) {
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($cpAuthKey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
$sign = base64_encode($sign);
return $sign;
}
There is no big difference between signature methods. It should be noted that the private key here is the payment private key