当前位置: 首页 > article >正文

PHP在做api开发中,RSA加密签名算法如何使用 ?

RSA 加密是什么

RSA(Rivest-Shamir-Adleman)是最早的公钥密码系统之一,广泛用于安全数据传输。3 位数学家 Rivest、Shamir 和 Adleman 的名字来命名的。

是非对称加密的一种 这种算法非常可靠,密钥越长,它就越难破解。

在这样的密码系统中,加密密钥是公共的,并且它与保密(私有)的解密密钥不同

加密

RSA 密码体制是一种公钥密码体制,加密算法公开,以分配的密钥作为加密解密的关键

一般来说,在一对公私钥中,公钥和私钥都可以用来加密和解密,即公钥加密能且只能被对应的私钥进行解密

私钥加密能且只能被对应的公钥进行解密。

一般我们都是把公钥公开出去 如果我们是服务方 一般我们是拿私钥加密 接收方来拿公钥进行验签等

为了保证加密安全 建议 RSA 密钥的长度为 2048

签名

签名就是在这份资料后面增加一段强而有力的证明,以此证明这段信息的发布者和这段信息的有效性完整性。

简单来说,签名主要包含两个过程:摘要 和 非对称加密,首先对需要签名的数据做摘要(类似于常见的 MD5)后得到摘要结果。

然后通过签名者的私钥对摘要结果进行非对称加密即可得到签名结果

支付中签名的套路

来说下对接的支付中的签名,拿 支付宝 举例

生成签名

1. 生成参数并进行 url_encode 然后按照字典排序,组成字符串 等到待签名字符串。

2. 获取私钥 然后使用各自语音的加密方法 对待签名字符串进行加密

3. 得到签名 (sign) 后并进行 base64 转码

4. 把加密字符串的的数组 和 签名 一并发给接受方

验证签名

1. 在通知返回参数列表中,除去 签名参数 (sign ) 以及空的参数 其他的全部都是待签名的参数。

2. 将剩下参数进行 url_decode, 然后进行字典排序, 使用 & = 组成字符串,得到待签名字符串。

3. 将签名参数(sign)使用 base64 解码为字节码串。

4. 使用 RSA 的验签方法,通过签名字符串、签名参数(经过 base64 解码)及支付宝公钥验证签名,根据返回结果判定是否验签通过

PHP 中 OpenSSL 的使用

php 的扩展中有 OpenSSL 库 可以用来操作 对称/非对称的加密 算法

下面贴段大概的 PHP 示例代码

生成待 签名 / 验签 的字符串

/**
 * 生成待签名的字符串
 * @param $data 参与签名的参数数组
 * @return string 待签名的字符串
 */
function getSignStr($data)
{
    //排序
    ksort($data);
    //剔除sign 如果对方的签名叫sign 或者可以在调用方法的时候剔除
    //unset($data['sign']);

    $stringToBeSigned = '';

    $i = 0;

    foreach ($data as $k => $v) {
        if ($i == 0) {
            $stringToBeSigned .= "$k" . "=" . "$v";
        } else {
            $stringToBeSigned .= "&" . "$k" . "=" . "$v";
        }

        $i++;
    }

    return $stringToBeSigned;
}
生成签名,返回签名字符串sign
/**
 * 生成签名
 * @param array $params 待签名的所有参数
 * @return string 生成的签名
 */
function getSignGenerator($params)
{
    //生成待验签的字符串
    $data = $this->getSignStr($params);
    //私钥的内容 一行的格式
    $privateKey = 'xxx';

    $pem = "-----BEGIN RSA PRIVATE KEY-----\n" .
        wordwrap($privateKey, 64, "\n", true) .
        "\n-----END RSA PRIVATE KEY-----";

    //openssl_private_encrypt($data, $crypted, $pem);
    openssl_sign($data, $sign, $pem, OPENSSL_ALGO_SHA256);

    $sign = base64_encode($sign);

    return $sign;
}

验证签名


/**
 * 验证签名
 * @param array $params 待签名的所有参数
 * @param string $sign 生成的签名
 * @return boolean 校验的结果
 */
function signCheck($params, $sign)
{
    //生成待验签的字符串
    $data = $this->getSignStr($params);
    //对方的公钥内容 一行的形式
    $publicKey = 'xxx';

    $pem = "-----BEGIN PUBLIC KEY-----\n" .
        wordwrap($publicKey, 64, "\n", true) .
        "\n-----END PUBLIC KEY-----";

    $checkResult = (bool)openssl_verify($data, base64_decode($sign), $pem, OPENSSL_ALGO_SHA256);

    return $checkResult;
}

自己的加密方法

/**
 * 我们自己的加密
 * @param $str 待加密的字段
 * @return string
 */
function encrypt($string)
{
    //公钥内容 一行的形式
    $pubKey = 'xxxx';

    $res = "-----BEGIN PUBLIC KEY-----\n" .
        wordwrap($pubKey, 64, "\n", true) .
        "\n-----END PUBLIC KEY-----";

    openssl_public_encrypt($string, $encrypt, $res);

    return base64_encode($encrypt);
}

自己的解密方法

/**
 * 我们自己的解密
 * @param $secret 加密后的base64字段
 * @return string
 */
function decrypt($secret)
{
    //私钥内容 一行的形式
    $privateKey = 'xx';

    $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
        wordwrap($privateKey, 64, "\n", true) .
        "\n-----END RSA PRIVATE KEY-----";

    openssl_private_decrypt(base64_decode($secret), $oldData, $res);

    return $oldData;
}

注意:主要使用到下面几个函数 分别都是对应的

私钥加密 openssl_private_encrypt => 公钥解密 openssl_public_decrypt

公钥加密 openssl_public_encrypt => 私钥解密 openssl_private_decrypt

使用的时候分别使用对应的公钥 / 私钥的文件内容即可,我是把公钥和私钥都配置了一行形式 (也就是没有换行符等 方便配置吧)。


http://www.kler.cn/a/467377.html

相关文章:

  • AWS Auto Scaling基础知识
  • [LeetCode-Python版]Hot100(1/100)——49. 字母异位词分组
  • AI在电子制造中的应用:预测质量控制
  • 小结:DNS,HTTP,SMTP,IMAP,FTP,Telnet,TCP,ARP,ICMP
  • 【Rust自学】10.3. trait Pt.1:trait的定义、约束与实现
  • spring mvc源码学习笔记之六
  • Fabric环境部署-Git和Node安装
  • 蛋白互作组学系列丨(四)IP-MS数据分析
  • 基础图形化界面的一个图片爬虫期末
  • 【初阶数据结构与算法】排序算法总结篇(每个小节后面有源码)(直接插入、希尔、选择、堆、冒泡、快速、归并、计数以及非递归快速、归并排序)
  • uniapp【拨打电话,发送消息】
  • 什么是TDD测试驱动开发(Test Driven Development)?
  • 【架构设计(一)】常见的Java架构模式
  • PDF阅读和编辑工具——xodo
  • 免费下载 | 2024中国大数据产业白皮书
  • MYSQL----------字符集
  • 一文讲清楚HTTP常见的请求头和应用
  • opencv与halcon的差距及改进方法
  • 浅谈文本匹配
  • 深入Android架构(从线程到AIDL)_10 主线程(UI 线程)的角色
  • [Day 12]904.水果成篮
  • cpp编译链接等
  • Java 关键字【synchronized】
  • 智慧招商宣传系统(源码+文档+部署+讲解)
  • 香橙派安装 opencv 4.9.0
  • C++文件流 例题