PHP实现RSA2加密

限于喜欢 提交于 2020-01-22 05:20:39

因为做支付宝APP支付需要把订单信息结合支付密钥进行加密,所以需要一个完成加密的接口。

整体代码下面会有,不过在代码之前有几个需要注意的点。

首先,php扩展openssl需要打开,这个可以phpinfo查看是否开启。

Linux宝塔是上安装的php是默认开启的

接着,在php.ini文件中搜索extension,找到extension = openssl去掉前面的冒号

在phpstudy中是extension = openssl.dll

这里有一点,好多博文都没有提到,所以我踩过这个坑。(就是密钥和公钥的格式问题)

 private static $PRIVATE_KEY = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
这里是密钥内容
-----END RSA PRIVATE KEY-----
EOD;
   
   private static $PUBLIC_KEY  = <<<EOD
-----BEGIN PUBLIC KEY-----
这里是公钥内容
-----END PUBLIC KEY-----
EOD;

如果想把代码放到.pem文件中,也用这种格式,之后使用file_get_contents()函数获取到即可

还有一点需要注意,PHP传参会自动转义,如果是把加密功能写成一个接口,那么需要加密的数据就会以参数的形式传进来,就需要解决PHP转义这个问题。

假设 $data是传来的参数

$str = htmlspecialchars_decode($data);

这个函数,可以把参数进行反转义,变回最初的样子。

下面是一个可以单独执行的php代码,可以直接测试加密和验证

<?php

class Rsa2
{
    private static $PRIVATE_KEY = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
////////
-----END RSA PRIVATE KEY-----
EOD;
   
   private static $PUBLIC_KEY  = <<<EOD
-----BEGIN PUBLIC KEY-----
\\\\\\\\
-----END PUBLIC KEY-----
EOD;

    /**
     * 获取私钥
     * @return bool|resource
     */
    private static function getPrivateKey()
    {
        $privKey = self::$PRIVATE_KEY;
        return openssl_pkey_get_private($privKey);
    }

    /**
     * 获取公钥
     * @return bool|resource
     */
    private static function getPublicKey()
    {
        $publicKey = self::$PUBLIC_KEY;
        return openssl_pkey_get_public($publicKey);
    }

    /**
     * 创建签名
     * @param string $data 数据
     * @return null|string
     */
    public function createSign($data = '')
    {
        if (!is_string($data)) {
            return null;
        }
        return openssl_sign(
                    $data,
                    $sign,
                    self::getPrivateKey(),
                    OPENSSL_ALGO_SHA256
                  ) ? urlencode(base64_encode($sign)) : null;
    }

    /**
     * 验证签名
     * @param string $data 数据
     * @param string $sign 签名
     * @return bool
     */
    public function verifySign($data = '', $sign = '')
    {
        if (!is_string($sign) || !is_string($sign)) {
            return false;
        }
        return (bool)openssl_verify(
                      $data,
                      base64_decode($sign),
                      self::getPublicKey(),
                      OPENSSL_ALGO_SHA256
                    );
    }
}


$rsa2 = new Rsa2();
$content = 'app_id=2019121069836088&biz_content={"timeout_express":"30m","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.01","subject":"1","body":"我是测试数据","out_trade_no":"12345678"}&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2&timestamp=2020-01-04 16:55:53&version=1.0'; //待签名字符串

$strSign = $rsa2->createSign($content);      //生成签名

echo "原文 --> $content\n";
echo "签名后 --> $strSign\n";

$is_ok = $rsa2->verifySign($content, $strSign); //验证签名0 

echo "验证签名 --> $is_ok\n";

加密之后验证加密是否正确,就调用验证的方法,验证方法的参数1为原字符串,参数2为加密后的字符串,结果放回1为验证成功。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!