PHP 实现 SHA256 with RSA 签名 (实例讲解)

背景

  • 近期在对接 美餐支付 接口文档时,
    重点需根据 sha256WithRSA 签名规则,进行加密处理
    通过参考网上的签名经验,最后整理出适合自己业务使用的处理方法
    欢迎各位指摘 …

实现方式

  • 签名加密、解密代码:
    /**
     * @Notes:生成 sha256WithRSA 签名
     * 提示:SPKI(subject public key identifier,主题公钥标识符)
     * @param null $signContent     待签名内容
     * @param string $privateKey    私钥数据(如果为单行,内容需要去掉RSA的标识符)
     * @param bool $singleRow       是否为单行私钥-标识
     * @return string               签名串
     * @User: zhanghj
     * @DateTime: 2023-09-27 9:41
     */
    public function getSHA256SignWithRSA($signContent = null, $privateKey = '', $singleRow = false){
        if ($singleRow){
            //如果传入的私钥是单行数据,且没有RSA的标识符,需做格式转化
            $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
                          wordwrap($privateKey, 64, "\n", true) .
                          "\n-----END RSA PRIVATE KEY-----";
        }
        $key = openssl_get_privatekey($privateKey);
        //开始加密
        openssl_sign($signContent, $signature, $key, OPENSSL_ALGO_SHA256);
        //进行 base64编码 加密后内容
        $encryptedData = base64_encode($signature);
        openssl_free_key($key);
        return $encryptedData;
    }

    /**
     * @Notes:验证 sha256WithRSA 签名
     * @param null $signContent     待签名内容
     * @param string $signatureStr  签名串
     * @param string $public_key    公钥数据(如果为单行,内容需要去掉RSA的标识符)
     * @param bool $singleRow       是否为单行私钥-标识
     * @return int                  1:签名成功,0:签名失败
     * @User: zhanghj
     * @DateTime: 2023-09-27 10:38
     */
    public static function verifySha256SignWithRSA($signContent = null, $signatureStr = '', $public_key = '',$singleRow = false)
    {
        if ($singleRow){
            $public_key = "-----BEGIN PUBLIC KEY-----\n" .
                wordwrap($public_key, 64, "\n", true) .
                "\n-----END PUBLIC KEY-----";
        }
        $key = openssl_get_publickey($public_key);
        $ok = openssl_verify($signContent, base64_decode($signatureStr), $key, OPENSSL_ALGO_SHA256);
        openssl_free_key($key);
        return $ok;
    }
  • 签名加密,操作举例
/**
 * 1. 如果得到的 私钥数据,没有RSA标识符,此时,要求私钥为【单行】形式
 */
$signature_res = self::getSHA256SignWithRSA($sign_str,$this->private_key,true);

/**
 * 2. 如果得到的 私钥数据,拥有RSA标识符,此时,要求私钥为标准的形式(每行64个字符)
 */
$signature_res = self::getSHA256SignWithRSA($sign_str,$this->private_key,false);

/**
 * 3. 如果得到的 私钥数据,是以 pem文件形式存储,此时,需先加载指定目录的 pem文件
 */
// 加载私钥文件
$this->private_key = openssl_pkey_get_private(file_get_contents(self::KEY_FILE_DIR.'rsa_private.pem'));        
$signature_res = self::getSHA256SignWithRSA($sign_str,$this->private_key,false);

附录

① . 参考文章

②. GuzzleHttp 使用技巧

    1. 实例化类 Client

配置参数 http_errors 可解决 401 授权问题

//实例化 Client
$httpClient = new Client([
            'base_uri' => self::BASE_URL,
            'verify' => false,
            'http_errors' => false]);

//请求传参            
$options = [
                'timeout' => 5,
                //传输 headers
                'headers' => $header_data,
            ];
            
//判断请求方式
if ($request_method == 'GET'){
    $options['query'] = $request_body;
}else{
    //参数需在请求JSON传参
    //$options['form_params'] = $request_body;
    $options['json'] = $request_body;
}

//请求目标接口,处理反馈信息
$response  = $this->httpClient->request($request_method,$url,$options);
$contents = $response->getBody().'';
$opData = json_decode($contents,true);

. 签名提示

    1. 如果使用了 json_encode($arr,JSON_UNESCAPED_UNICODE) 类似编码,目的是为了不让中文乱码
      但是,有的签名验证会因为这个原因,提示签名错误
      原因在于:签名前的数据,和签名后的数据 在处理时可能因为编码不一致,造成识别有误

启发来源:美餐支付 作退款接口开发时,因为这个原因造成 耗时排查!

### 如何在 Windows 11 上完全卸载 MySQL #### 停止并删除 MySQL 服务 为了确保 MySQL 不再作为后台进程运行,需停止其服务。这可通过命令提示符完成: ```cmd net stop mysql ``` 随后,利用 `sc` 工具来移除不再需要的服务条目[^4]。 #### 卸载 MySQL 应用程序及其组件 访问控制面板中的“应用”部分,定位所有与 MySQL 相关的应用程序,并逐一进行卸载操作。此过程有助于清除大部分由安装包写入系统的数据[^3]。 #### 清理残留文件夹 检查标准安装位置如 `C:\Program Files\MySQL` 和 `C:\Program Files (x86)\MySQL` 下是否存在任何未被自动处理掉的 MySQL 文件夹,并手动将其彻底删除以防止未来可能出现冲突的情况发生。 #### 移除注册表项 启动注册表编辑器 (`regedit`) 并导航至 `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services` 路径下寻找名为 "mysql" 的键值,对其进行安全备份之后实施删除动作,从而消除潜在影响新版本安装的因素存在可能性。 #### 更新环境变量配置 核查系统属性内的高级设置里的环境变量列表,去除那些指向旧版 MySQL 安装路径的相关条目,保证后续开发环境中不会因遗留设定而出现问题。 #### 删除剩余的服务实例 对于某些情况下未能成功移除的服务记录,可以再次借助命令行工具执行如下指令实现最终清理目的: ```cmd sc delete mysql ``` 注意替换上述命令中的 'mysql' 字样为你实际遇到的具体服务名称[^5]。 #### 系统重启确认变更效果 最后一步也是至关重要的环节——重新启动计算机,以此让之前所做的各项调整正式生效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值