zoukankan      html  css  js  c++  java
  • PHP RSA参数签名

    为了防止在支付通信过程中的参数数据被篡改或者伪造,采用RSA进行数据签名和验证签名。

    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

    生成公私钥:

    生成 RSA 私钥 PEM 文件:

    openssl genrsa -out rsa_private_key.pem 2048

    根据已经生成的私钥再生成公钥:

    openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

    注意:生成后的rsa_private_key.pem私钥不能直接用于java进行加密,原因是java使用的PKCS#8格式的私钥,但PHP不会有问题。java的keytool生成的rsa公钥密私钥是16进制字符串,php用openssl生成的公钥私钥是基于base64格式的字符串或者二进制格式,这两种不同的公约密钥并不能直接转化。

    签名验证:

    首先URL的参数请用'key'的字母顺序排序,然后对整个URL,除了sign签名参数之外的部分做签名,以参数名sign做urlencode处理后加在URL后面。比如如下红色的部分为签名的原始字符串数据,蓝色部分为追加的签名值。

    changba://game/goldpay?access_token=xxxxxxxx&id=yourgameid&orderid=111111&ordesc=%E8%B4%AD%E4%B9%B0%E4%B8%80%E4%B8%AAXX%E6%B8%B8%E6%88%8FXX%E6%AD%A6%E5%99%A8&payredirect_uri=game%3a%2f%2fchangba%2fpay&price=100&ver=1.0&sign=o8z82NNFYggbYC/kcPztSrXtTVa39A7eqyxhcNtvXRteHl8nvcNFmhrjk9lhz0Td877m4xUGb6LnEcs4acoeQnUtub6Yn1Y9sLtbQ1kBTTbD9oV2Ru0Gu4HutA/iJZWtFrzcvUo/JsZOCT4Vn9XtLGWFgvaPCpDqUF49/HBvJIVr/jMk2Ww2FuZgieIH8qBVHxTAoLdJfD2kwEMIPo9y/i3qbnluAmPC0vvuUZPaFohVn0M9BXps83c7750JaMJuFRarpC/Xp6gUjOm5neSbcwWBe7kHPWPIOjLTmQSWUlsf/Mu/Bhd/neHwzoUwqJbOotGRIFC6pfXiQhc6oidAxQ==

    注意签名的字符串数据中参数值必须是urlencode处理过的,签名值需要再做base64编码以及urlencode处理,以备当做sign URL参数传递。

    验签的时候需要先进行base64解码,然后才进行验证签名。

    class ChangbaRsaSign {
    
        /**RSA签名函数
    
         * $data为待签名数据,比如URL
    
         * 签名用游戏方的保密私钥,必须是没有经过pkcs8转换的.结果需要用base64编码以备在URL中传输
    
         * return Sign 签名
    
         */
    
        public static function sign($data) {
    
            $priKey = file_get_contents('key/rsa_private_key.pem');
    
            //转换为openssl密钥,必须是没有经过pkcs8转换的私钥
    
            $res = openssl_get_privatekey($priKey);
    
            //调用openssl内置签名方法,生成签名$sign
    
            openssl_sign($data, $sign, $res);
    
            openssl_free_key($res);
    
     
    
            $sign = base64_encode($sign);
    
            return $sign;
    
        }
    
     
    
        /**RSA验证签名
    
         * $data为要验证的数据字符串
    
         * $sign是需要验证的签名数据,是直接从URL中取到的$_POST["sign"]型参数,函数里面会进行base64_decode的。
    
         * return 验签是否通过,为BOOL值
    
         */
    
        public static function verify($data, $sign)  {
    
            //读取公钥文件,也就是签名方公开的公钥,用来验证这个data是否真的是签名方发出的
    
            $pubKey = file_get_contents('key/rsa_public_key.pem');
    
     
    
            $res = openssl_get_publickey($pubKey);
    
            //调用openssl内置方法验签,返回bool值
    
            $result = (bool)openssl_verify($data, base64_decode($sign), $res);
    
     
    
            openssl_free_key($res);
    
            return $result;
    
        }
  • 相关阅读:
    (Ubuntu)Tensorflow object detection API——(2)运行已经训练好的模型
    tensorflow object detection API 验证时报No module named 'object_detection'
    (Ubuntu)Tensorflow object detection API——(1)环境搭建
    将图片数据保存为单个tfrecord文件
    线性系统和非线性系统
    一次 Druid 连接池泄露引发的血案!
    46 道阿里巴巴 Java 面试题,你会几道?
    想成为顶尖 Java 程序员?先过了下面这些问题!
    干掉PostMan!IDEA这款插件太实用了…
    网络常见的 9 大命令,非常实用!
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4608041.html
Copyright © 2011-2022 走看看