PHP RSA公私鑰的理解和示例說明


1、生成公鑰和私鑰

要應用RSA算法,必須先生成公鑰和私鑰,公鑰和私鑰的生成可以借助openssl工具。
也可以用在線生成公私鑰。(網站:http://web.chacuo.net/netrsakeypair) 密鑰位數:1024位,密鑰格式:PKCS#1 示例生成如下:

公鑰的內容:
1 -----BEGIN PUBLIC KEY-----
2 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgFeb3f1f9lwrLrqoNpmODMZe7
3 eO2t1yzfpY32QacYA/NISqkV6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu4
4 6KBsgo3p6xcxEUPJNABNGU05YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYET
5 uqkpR4bN5afMZNmGbQIDAQAB
6 -----END PUBLIC KEY-----

私鑰的內容:
 1 -----BEGIN RSA PRIVATE KEY-----
 2 MIICWwIBAAKBgQCgFeb3f1f9lwrLrqoNpmODMZe7eO2t1yzfpY32QacYA/NISqkV
 3 6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu46KBsgo3p6xcxEUPJNABNGU05
 4 YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYETuqkpR4bN5afMZNmGbQIDAQAB
 5 AoGALTsjACj93ovPpA8cwzCRC192xKR9W1HhvusS+lJAePucwH8/2Q4dbPV7juKD
 6 SwpRCeZwmIv2MvPT+5jnjvUZylkwMbLHwlb5UcB7cYr/vtZvPz2O2ZNU3jiw7Z9U
 7 Ue/27c3EnIHeIb5PBf9SwTlq1iA79nf5Qb50ontDemf2pY0CQQCse7KkHwOEXk4i
 8 ZnjVCB8J3ir7XBP7VFG/pRuGsr5y99hhEyUd+yznIQgPiDjC3uoIP1gsBbs5LqOV
 9 Sx5ltLHfAkEA7Zlxxa5lPHWGqXFb1fbtq5Ou/228f/qmuMqpXf8BlUAzQ8SFjC3t
10 jwnL83zMWxgjaqSrXmuNeICay+5/eA7JMwJAbjIBKZWe25yccqHhJMkxe05zS2/C
11 XFm8eKH1ehMMVcs+dJaUqhjk0S1rRvESwn1EK8y8ejOXL6s6W5FIdFYDJQJAbJ4h
12 LMW08haoIP35ha8Ep9MzxQFdkwP7A69iDd5t0tUummRUyOiWGTXZTs5Wfa5jQnVV
13 Ai0Y12WzXlcBXtkjkQJASXjgltdFr/q7gFbZiG6C2/eDz0Ce79dLPShi95uzjYOX
14 emgrKYbLCyqZXJgWoS9Y/k0kAyZTGHJ9O00JRDH87Q==
15 -----END RSA PRIVATE KEY-----
常規:公鑰和私鑰生成好了之后,私鑰自己保存,將公鑰交給第三方即可。


2、php的RSA加密解密

在做加密解密之前,首先要確保php已經開啟了openssl拓展,可以通過phpinfo()函數進行查看。
通常情況下,有以下兩種情形:
①通過公鑰加密,通過私鑰解密;
②通過私鑰加密,通過公鑰解密;
示例解釋:支付寶的業務場景屬於第二種情形.
業務方 向 支付寶 發送支付請求,將sign參數通過自己的私鑰加密過后發送到支付寶的接口; (業務方簽名sign 屬於第二種情形:加密.)
支付寶 向 業務方 發送支付回調結果,將sign參數通過自己的私鑰加密過后發送到業務方的notify接口;(解密支付寶回調sign驗簽 屬於第二種情形:解密 可俗稱驗簽.)
注:支付寶使用的加密函數是openssl_sign,之后的校驗可以使用openssl_verify函數進行校驗。

//公私鑰加密示例代碼:
 1     $content = '待加密的字符串,自己替換';
 2     //示例直接取私鑰內容,自己替換
 3     //注意:priKey是一串連續字符,如果存在空格需要去除
 4     $priKey = 'MIICWwIBAAKBgQCgFeb3f1f9lwrLrqoNpmODMZe7eO2t1yzfpY32QacYA/NISqkV';
 5     $priKey .='6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu46KBsgo3p6xcxEUPJNABNGU05';
 6     $priKey .='YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYETuqkpR4bN5afMZNmGbQIDAQAB';
 7     $priKey .='AoGALTsjACj93ovPpA8cwzCRC192xKR9W1HhvusS+lJAePucwH8/2Q4dbPV7juKD';
 8     $priKey .='SwpRCeZwmIv2MvPT+5jnjvUZylkwMbLHwlb5UcB7cYr/vtZvPz2O2ZNU3jiw7Z9U';
 9     $priKey .='Ue/27c3EnIHeIb5PBf9SwTlq1iA79nf5Qb50ontDemf2pY0CQQCse7KkHwOEXk4i';
10     $priKey .='ZnjVCB8J3ir7XBP7VFG/pRuGsr5y99hhEyUd+yznIQgPiDjC3uoIP1gsBbs5LqOV';
11     $priKey .='Sx5ltLHfAkEA7Zlxxa5lPHWGqXFb1fbtq5Ou/228f/qmuMqpXf8BlUAzQ8SFjC3t';
12     $priKey .='jwnL83zMWxgjaqSrXmuNeICay+5/eA7JMwJAbjIBKZWe25yccqHhJMkxe05zS2/C';
13     $priKey .='XFm8eKH1ehMMVcs+dJaUqhjk0S1rRvESwn1EK8y8ejOXL6s6W5FIdFYDJQJAbJ4h';
14     $priKey .='LMW08haoIP35ha8Ep9MzxQFdkwP7A69iDd5t0tUummRUyOiWGTXZTs5Wfa5jQnVV';
15     $priKey .='Ai0Y12WzXlcBXtkjkQJASXjgltdFr/q7gFbZiG6C2/eDz0Ce79dLPShi95uzjYOX';
16     $priKey .='emgrKYbLCyqZXJgWoS9Y/k0kAyZTGHJ9O00JRDH87Q==';
17 
18     echo createSign($content,$priKey);
19 
20     /**
21      * 創建RSA加密簽名
22      * @param string $content
23      * @param string $priKey
24      * @return mixed
25      */
26     function createSign($content, $priKey){
27         //轉換成PrivateKey格式
28         $priKey = convertPrivateKey($priKey);
29         //獲取私鑰內容
30         $openssl_private_key =  openssl_get_privatekey($priKey);
31         //對數據進行PKCS1簽名   簽名還有MD5,SHA,RMD根據自己實例代碼修改
32         //openssl_sign($content, $signature, $openssl_private_key, OPENSSL_ALGO_MD5);
33         @openssl_private_encrypt($content, $signature, $openssl_private_key, OPENSSL_PKCS1_PADDING);
34         //釋放資源
35         @openssl_free_key($openssl_private_key);
36         //對簽名進行Base64編碼,變為可讀的字符串
37         $sign = base64_encode($signature);
38         if (empty($sign)) {
39             return false;
40         }
41         return $sign;
42     }
43 
44     /**
45      * 轉換PrivateKey
46      * @param string $priKey
47      * @return string
48      */
49     function convertPrivateKey($priKey) {
50         //判斷是否傳入私鑰內容
51         $private_key_string = !empty($priKey) ? $priKey : '';
52         //64位換行私鑰內容
53         $private_key_string = chunk_split($private_key_string, 64, "\r\n");
54         //私鑰頭部
55         $private_key_header = "-----BEGIN RSA PRIVATE KEY-----\r\n";
56         //私鑰尾部
57         $private_key_footer = "-----END RSA PRIVATE KEY-----";
58         //完整私鑰拼接
59         $private_key_string = $private_key_header.$private_key_string.$private_key_footer;
60         return $private_key_string;
61     }
獲取sign簽名如下: "TFFHwGlMYgANXiwC+aAu122+K3R0n+Ig5ZfpmqNLEYjeS/EwMSUaYA4V5+aXAklRcSPDyJoERZ2+4sUQP1UGWqcwiKuoiHiZ8Ps1ljrBfQpATHrljyLdrj3yZSa2cOqQArBtCxFB9DGDZsbrsbOl7H/zfl3quKDKoiCwQedaykU="


//公私鑰解密示例代碼:
 1       $sign = "TFFHwGlMYgANXiwC+aAu122+K3R0n+Ig5ZfpmqNLEYjeS/EwMSUaYA4V5+aXAklRcSPDyJoERZ2+4sUQP1UGWqcwiKuoiHiZ8Ps1ljrBfQpATHrljyLdrj3yZSa2cOqQArBtCxFB9DGDZsbrsbOl7H/zfl3quKDKoiCwQedaykU=";
 2       //示例直接取公鑰內容,自己替換
 3       //注意:publickey,如果存在空格需要去除
 4       $publickey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgFeb3f1f9lwrLrqoNpmODMZe7';
 5       $publickey .= 'eO2t1yzfpY32QacYA/NISqkV6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu4';
 6       $publickey .='6KBsgo3p6xcxEUPJNABNGU05YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYET';
 7       $publickey .='uqkpR4bN5afMZNmGbQIDAQAB';
 8       echo checkSign($sign,$publickey);
 9 
10       /**
11        * RSA解密(驗簽)
12        * @param string $sign
13        * @param string $publickey
14        * @return 0 or 1
15        */
16         function checkSign($sign, $publickey){
17             //轉換成PublicKey格式
18             $publickey = convertPublicKey($publickey);
19             //獲取公鑰鑰內容
20             $openssl_public_key = @openssl_get_publickey($publickey);
21             //對數據進行解密
22             //$result = @openssl_verify($content,base64_decode($sign), $openssl_public_key,OPENSSL_ALGO_MD5);
23             $result = openssl_public_decrypt(base64_decode($sign), $decrypted, $openssl_public_key,OPENSSL_PKCS1_PADDING);
24             //釋放資源
25             @openssl_free_key($openssl_public_key);
26             return $result;
27         }
28 
29         /**
30          * 轉換PublicKey
31          * @param string $publicKey
32          * @return string
33          */
34         function convertPublicKey($publicKey) {
35             //判斷是否傳入公鑰內容
36             $public_key_string = !empty($publicKey) ? $publicKey : '';
37             //64位換行公鑰鑰內容
38             $public_key_string = chunk_split($public_key_string, 64, "\r\n");
39             //公鑰頭部
40             $public_key_header = "-----BEGIN PUBLIC KEY-----\r\n";
41             //公鑰尾部
42             $public_key_footer = "-----END PUBLIC KEY-----";
43             //完整公鑰拼接
44             $public_key_string = $public_key_header.$public_key_string.$public_key_footer;
45             return $public_key_string;
46         }
驗證返回值是: 1驗簽成功  0驗簽失敗







免責聲明!

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



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