HarmonyOS 鸿蒙Next 华为签名SHA256WithRSA/PSS php实现求助

发布于 1周前 作者 zlyuanteng 来自 鸿蒙OS

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

中的签名机制

5 回复
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>&nbsp; 这是我写的例子</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_signopenssl_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。

回到顶部