HarmonyOS 鸿蒙Next 华为签名SHA256WithRSA/PSS php实现求助
HarmonyOS 鸿蒙Next 华为签名SHA256WithRSA/PSS php实现求助
华为鸿蒙系统大部分签名使用SHA256WithRSA/PSS签名算法,php中openssl_sign好像只能实现SHA256WithRSA,签名出来的和给出的例子的签名有所出入
大家怎么使用php进行SHA256WithRSA/PSS签名的呢
参考文档地址:
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/gameservice-unbindplayer-V5
中的签名机制
use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\RSA;
function getOtherSign($params,$rsa_key){
if(isset($params[‘sign’])) unset($params[‘sign’]);
if(isset($params[‘method’])) unset($params[‘method’]);
ksort($params); //键按a-z升序
$rSign = ‘’;
foreach($params as $key => $val){
if( $val != ‘’ && !is_null($val)){//空字符串和null不参与签名
$rSign .= $key.’=’.urlencode($val).’&’;
}
}
$rSign = (rtrim($rSign,’&’));
$key = “-----BEGIN PRIVATE KEY-----\n” . chunk_split($rsa_key, 64, “\n”) . “-----END PRIVATE KEY-----”;
$private = PublicKeyLoader::load($key, $password = false);
$private = $private->withPadding(RSA::SIGNATURE_PSS);
return base64_encode($private->sign($rSign));
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
引入第三库可以解决这个签名问题
phpseclib3
private function getOtherSign($params,$rsa_key){
if(isset($params['sign'])) unset($params['sign']);
if(isset($params['method'])) unset($params['method']);
ksort($params); //键按a-z升序
$rSign = '';
foreach($params as $key => $val){
if( $val != '' && !is_null($val)){//空字符串和null不参与签名
$rSign .= $key.'='.urlencode($val).'&';
}
}
$rSign = (rtrim($rSign,'&'));
//print_r($rSign);
$key = "-----BEGIN RSA PRIVATE KEY-----\n" . chunk_split($rsa_key, 64, "\n") . "-----END RSA PRIVATE KEY-----";
$res = openssl_get_privatekey($key);
// $public_key_header = “-----BEGIN PRIVATE KEY-----\r\n”;
// $public_key_footer = “\r\n-----END PRIVATE KEY-----”;
// $res = $this->convert_publicKey($rsa_key,$public_key_header,$public_key_footer);
//$res = openssl_pkey_get_private($res);
openssl_sign($rSign, $sign, $res, OPENSSL_ALGO_SHA256);
<span class="hljs-variable"><span class="hljs-variable">$sign</span></span> = base64_encode(<span class="hljs-variable"><span class="hljs-variable">$sign</span></span>);
<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-variable"><span class="hljs-variable">$sign</span></span>;
}</code><button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button></pre> <p> 这是我写的例子</p> <p>运行环境php 7.3.1还是返回签名错误</p> <p>rtnCode":1,"errMsg":"Check sign failed"</p></div></div>
1. 生成密钥对(如果你还没有密钥对的话):
$config = [
"digest_alg" => "sha256",
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
];
// 创建新的私钥和公钥对
$res = openssl_pkey_new($config);
// 从密钥资源中提取私钥
openssl_pkey_export($res, $privateKey);
// 从密钥资源中提取公钥
$publicKey = openssl_pkey_get_details($res)[“key”];
echo “Private Key:\n” . $privateKey . “\n”;
echo “Public Key:\n” . $publicKey . “\n”;
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
2. 签名数据:
$data = “Message to be signed”;
// 计算消息摘要
$digest = openssl_digest($data, ‘sha256’, true);
// 读取私钥
$privateKey = openssl_pkey_get_private($privateKey);
// 使用RSA-PSS算法进行签名
$signature = ‘’;
openssl_sign($data, $signature, $privateKey, OPENSSL_ALGO_SHA256);
echo "Signature: " . base64_encode($signature) . “\n”;
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
3. 验证签名:
// 使用RSA-PSS算法验证签名
$publicKey = openssl_pkey_get_public($publicKey);
$result = openssl_verify($data, $signature, $publicKey, OPENSSL_ALGO_SHA256);
if ($result === 1) {
echo “Verification successful\n”;
} elseif ($result === 0) {
echo “Verification failed\n”;
} else {
echo “Error during verification\n”;
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
注意,openssl_sign
和openssl_verify
函数在PHP 7.1.0之后支持PSS签名算法。如果你使用的PHP版本较低,请升级到7.1.0或更高版本。
private function getOtherSign($params,$rsa_key){ if(isset($params[‘sign’])) unset($params[‘sign’]); if(isset($params[‘method’])) unset($params[‘method’]); ksort($params); //键按a-z升序 $rSign = ‘’; foreach($params as $key => $val){ if( $val != ‘’ && !is_null($val)){//空字符串和null不参与签名 $rSign .= $key.’=’.urlencode($val).’&’; } } $rSign = (rtrim($rSign,’&’)); //print_r($rSign); $key = “-----BEGIN RSA PRIVATE KEY-----\n” . chunk_split($rsa_key, 64, “\n”) . “-----END RSA PRIVATE KEY-----”; $res = openssl_get_privatekey($key);
// $public_key_header = “-----BEGIN PRIVATE KEY-----\r\n”; // $public_key_footer = “\r\n-----END PRIVATE KEY-----”; // $res = $this->convert_publicKey($rsa_key,$public_key_header,$public_key_footer); //$res = openssl_pkey_get_private($res); openssl_sign($rSign, $sign, $res, OPENSSL_ALGO_SHA256);
$sign = base64_encode($sign);
return $sign;
}
运行环境php7.3.1,还是返回签名错误
在PHP中实现HarmonyOS鸿蒙Next的签名验证,特别是SHA256WithRSA/PSS,你可以使用openssl_verify
函数,但需要注意PHP的OpenSSL扩展可能默认不支持PSS填充模式。你可以通过OpenSSL命令行工具来生成签名,然后在PHP中验证。
在PHP中,你可以通过openssl_pkey_get_public
加载公钥,并使用openssl_verify
进行验证,但可能需要调整OpenSSL配置或使用第三方库来支持PSS。
请确保你的OpenSSL版本支持PSS,并在PHP中正确设置参数。如果问题依旧没法解决请加我微信,我的微信是itying888。