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;

    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM