因为做支付宝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×tamp=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为验证成功。
来源:CSDN
作者:耳东_晨
链接:https://blog.csdn.net/The_My_World/article/details/104060371