第一步、生成公私钥
密钥长度:
- RSA 密钥通常有不同的长度,通常以位数来表示,如 1024 位、2048 位等。一般来说,密钥长度越长,加密强度越高,但同时也会增加加密和解密的计算复杂度。一般推荐使用 2048 位或更长的 RSA 密钥来确保较高的安全性。
密钥格式:
- OpenSSL 中的私钥通常采用 PEM 格式(Privacy-Enhanced Mail,即隐私增强邮件)存储。PEM 格式的密钥是经过 Base64 编码的文本字符串,通常以
-----BEGIN PRIVATE KEY-----
开头,以-----END PRIVATE KEY-----
结尾。 - 另外,私钥也可以存储在 PKCS#12 格式的证书文件中,通常以
.p12
或.pfx
结尾。这些文件通常包含私钥、公钥和证书链等信息。
第二步、三种方式读取RSA密钥
第1种:公私钥弄成一行,必须一行没有空格和换行
1 2 | $publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKZ1mKTymRoGKnHiP1xAy4aiyt5r0BscCZnDAonCrMFZ4kBGriPNHxEaLr5lfBnMKw7k6i+2dsFPSEZooTvqtPUCAwEAAQ==' ; $privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApnWYpPKZGgYqceI/XEDLhqLK3mvQGxwJmcMCicKswVniQEauI80fERouvmV8GcwrDuTqL7Z2wU9IRmihO+q09QIDAQABAkBunx3nGHXYjppsfn++7iyTd+I7+Agfy/0xWyB3rpEiGGgfemjcRFaeq5SC2vUNXsrEOY5gbUSQmFxH//Cym18NAiEA1z1cZx/Q9cbIjFPwp1a+K5CVFDXDcfbi/AQgAkVs0/cCIQDF+2fr23AoBslcOC4S0yAx94AbgxCntYuRqztxybsrcwIgMW86ZcT87TX2oaQ1xXk6vC68zqN6fBZEE7Wu1Fa1pAkCIElmOJP3qfAc/AAlj+dIwLHlqWgJwl3674CU9Bfui2bDAiEA0CKJpF8x7KANCcopEQC93PsbIztuML322LOfDV1Lw/k=' ; |
转化能使用的密钥资源
- 如果私钥不是资源类型,则将私钥进行处理,将其转换为 PEM 格式。这里使用
chunk_split
函数将私钥按照每行64个字符的长度进行分割,并在适当的位置插入换行符n
。 - 在拼接完整的 PEM 格式私钥之后,再使用
openssl_pkey_get_private
函数将 PEM 格式的私钥转换为 OpenSSL 的私钥资源
1 2 3 4 5 | $pem = chunk_split ( $privateKey , 64, "n" ); $pem = "-----BEGIN PRIVATE KEY-----n" . $pem . "-----END PRIVATE KEY-----n" ; $pem2 = chunk_split ( $publicKey , 64, "n" ); $pem2 = "-----BEGIN PUBLIC KEY-----n" . $pem2 . "-----END PUBLIC KEY-----n" ; |
第2种:直接复制生成公私钥
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | $publicKeyString = "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1ffL+kUEedBLTzQrKU+ 8oq9IZSUroxhmnWrXa1XMGtlbeVCHQNljujqwGuLELyk7i78cGczwCyGE2SVj9oI tBzGn02fWZNCb3bHPv6ofliTvqYcZOFaFTWB+tTKuOmopCk/bgQVe7HC6+74s/3x Q4tM1jVbNPYSY11++DLjEQ8KaA3pNJwoFTxER3GVEgmfhi5xUTTaBa5ZOIaNfsFr 0fGzvGbmRpqoIor6MlSxXbMO4k2pMzB7YJYYr7zRC28DoeJCj5XnXkq4XPIJzo8/ g79163dp0y9m7cDn4NfRDdBsFeHy6n+hKps6hSVf1z1ZtQtlfk0mRE/EchubDcuH +QIDAQAB ----- END PUBLIC KEY-----"; $privateKeyString = "-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnV98v6RQR50Et PNCspT7yir0hlJSujGGadatdrVcwa2Vt5UIdA2WO6OrAa4sQvKTuLvxwZzPALIYT ZJWP2gi0HMafTZ9Zk0Jvdsc+/qh+WJO+phxk4VoVNYH61Mq46aikKT9uBBV7scLr 7viz/fFDi0zWNVs09hJjXX74MuMRDwpoDek0nCgVPERHcZUSCZ+GLnFRNNoFrlk4 ho1+wWvR8bO8ZuZGmqgiivoyVLFdsw7iTakzMHtglhivvNELbwOh4kKPledeSrhc 8gnOjz+Dv3Xrd2nTL2btwOfg19EN0GwV4fLqf6EqmzqFJV/XPVm1C2V+TSZET8Ry G5sNy4f5AgMBAAECggEAd5rFiV/EmXs4yVVzLEI7OG1S+oJQtmTdieFaZuzyqUfJ Sf+W/lekKb1ts7PpxD+gfiCVCt2oTk1EUu4MO7GxkNIUYF3Ba+tli3dQt0SaNxum FZhyKOQsV4ZT7WxTrFBM2XAlxsMie7M0xx6ZIUR6QTV56IxgMP1DbUOw8UKlqlV2 p3Vdckfjt2pWyLqM2yZUoC3+AjfqpJus/dpyIRGtLd8rLoFCrPgM2naEWxYCAeyI CpHgzYCCAbWyXZOkFOWIFPm53ZDbdZpupzKjS29rYGjiZ7St6sdCegGoZ+aYeUwA Bb1RKZjkBeLrxbuIZHlSbrBO12yE8gZ+VPzgSy1CVQKBgQDWHjj/7Yur/m+d9yJ0 9S14TK5KX3EX2cl46It8FMJEKTk1IhgYB6Dmk10pDrV2glJ3zLfwYeu82p9Zgswh F34mU3o67medJ3OJP+/qHYvEm4WOKw1973v8GEQhqTvr7yPYVC/cRoyN49FKbKfC sF7Scw7EaTObxtWMDJyaa+JDPwKBgQDIE3DhYzx1YahEHktYgVw9OaDdykzYZV2J KO8rkAwS0oXY6yi2J1nCrq3N5Ro7PAMCESRabgAps7n2GazLNfrtG/DcH87M0kYz AEwo1DvI3XVIAjiPmZXBeU2xp1o40OOxZXeHP3VzuU2ydyR6yp3Y2WCClmgf3Vuz O1uGk2A+xwKBgCZzbPcAuJldarvqWoS4Vr8Ivi/a7dtDn/uXfxz8OVq2MHDLO5pt HEbr5cnuu0WZ56dd2xZO71+Nvxn69B9pMZ0+Vm/oyjCdmhDmq3XWcngPGa/LKXQZ IqHF1c5ZrsoSutQpYiLjhHAinj4IPyQmOhD+2oMJBVyPG2A4D5Nnlk1PAoGBAIXH ognC3hEqzGVH0F+Ml82EdBD5DOsA1Es7KLj7J2eKht7lVqJ9q2ImhKaQkzqaRPSj 26fvt4Iq36QzxLtYC8FxllrJlfCUhUXi5AnE53jGw33zpjg2nNDyOEYavZQR8L2U OBkiEHnhpJc5XRYR1vvBVevbgCIWVBODFA7nCkrPAoGAK2oIQ5SLu5OfAB4qcN6v vHERc8JXGZWL/o2Z/4t0OX1X6NwDdAl87LCyQ6ab3dqmgemtjdd2Z9DDn2m9oPtO yuNvlxYNiCqgsNyUCwy6Q1yy1fOvhiUJF8rkq4UTSeQ8gSrf8hf3ajHmzhA1r5B7 Y5MUPUHIS6ckWMTF+pAXAgQ= ----- END PRIVATE KEY-----"; |
openssl_pkey_get_public
和openssl_pkey_get_private
是PHP OpenSSL扩展提供的两个函数。
openssl_pkey_get_public
函数用于获取公钥,它可以从一个证书文件或PEM格式的公钥字符串中提取公钥信息,并返回一个公钥资源
1 2 | $publicKeyResource = openssl_pkey_get_public( $publicKeyString ); $privateKeyResource = openssl_pkey_get_private( $privateKeyString ); |
第3种;复制密钥存储为.pem文件后缀
1 2 3 4 5 | $publicKeyString = file_get_contents ( 'public.pem' ); $privateKeyString = file_get_contents ( 'private.pem' ); $publicKeyResource = openssl_pkey_get_public( $publicKeyString ); $privateKeyResource = openssl_pkey_get_private( $privateKeyString ); |
第三步、RSA加解密
RSA加密
公钥加密 openssl_public_encrypt
=> 私钥解密 openssl_private_decrypt
私钥加密 openssl_private_encrypt
=> 公钥解密 openssl_public_decrypt
1. 公钥加密、私钥解密:
– 使用公钥加密数据:发送方使用接收方的公钥对数据进行加密。
– 使用私钥解密数据:只有拥有相应私钥的接收方才能使用私钥解密并获取原始数据。
2. 私钥加密、公钥解密:
– 使用私钥加密数据:发送方使用自己的私钥对数据进行加密。
– 使用公钥解密数据:接收方使用发送方的公钥来解密并获取原始数据。
1 |
第四步、RSA签名以及验证签名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /** * 构造签名 * @param string $dataString 被签名数据 * @return string */ public function sign( $dataString ) { $signature = false; openssl_sign( $dataString , $signature , $privKey ); return base64_encode ( $signature ); } /** * 验证签名 * @param string $dataString 被签名数据 * @param string $signString 已经签名的字符串 * @return number 1签名正确 0签名错误 */ public function verify( $dataString , $signString ) { $signature = base64_decode ( $signString ); $flg = openssl_verify( $dataString , $signature , $PubKey ); return $flg ; } |
第五步、封装完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | setKey( $publicKey , $privateKey , $type ); } public function setKey( $publicKey = null, $privateKey = null, $type =1) { if (! is_null ( $publicKey )) { $this ->setupPubKey( $publicKey , $type ); } if (! is_null ( $privateKey )) { $this ->setupPrivKey( $privateKey , $type ); } } private function setupPrivKey( $privateKey , $type ) { if ( is_resource ( $this ->privateKey)) { return true; } if ( $type == 1) { $pem = chunk_split ( $privateKey , 64, "n" ); $pem = "-----BEGIN PRIVATE KEY-----n" . $pem . "-----END PRIVATE KEY-----n" ; $this ->privateKey = openssl_pkey_get_private( $pem ); } elseif ( $type == 2) { $this ->privateKey = openssl_pkey_get_private( $privateKey ); } elseif ( $type == 3) { $privateKeyString = file_get_contents ( $privateKey ); $this ->privateKey= openssl_pkey_get_private( $privateKeyString ); } return true; } private function setupPubKey( $publicKey , $type =1) { if ( is_resource ( $this ->publicKey)) { return true; } if ( $type == 1) { $pem = chunk_split ( $publicKey , 64, "n" ); $pem = "-----BEGIN PUBLIC KEY-----n" . $pem . "-----END PUBLIC KEY-----n" ; $this ->publicKey = openssl_pkey_get_public( $pem ); } elseif ( $type == 2) { $this ->publicKey= openssl_pkey_get_public( $publicKey ); } elseif ( $type == 3) { $pubString = file_get_contents ( $publicKey ); $this ->publicKey= openssl_pkey_get_public( $pubString ); } return true; } public function privEncrypt( $data ) { if (! is_string ( $data ) || empty ( $this ->privateKey)) { return null; } $r = openssl_private_encrypt( $data , $encrypted , $this ->privateKey); if ( $r === true) { return base64_encode ( $encrypted ); } return null; } public function privDecrypt( $encrypted ) { if (! is_string ( $encrypted ) || empty ( $this ->privateKey)) { return null; } $encrypted = base64_decode ( $encrypted ); $r = openssl_private_decrypt( $encrypted , $decrypted , $this ->privateKey); if ( $r === true) { return $decrypted ; } return null; } public function pubEncrypt( $data ) { if (! is_string ( $data ) || empty ( $this ->publicKey)) { return null; } $r = openssl_public_encrypt( $data , $encrypted , $this ->publicKey); if ( $r === true) { return base64_encode ( $encrypted ); } return null; } public function pubDecrypt( $crypted ) { if (! is_string ( $crypted ) || empty ( $this ->publicKey)) { return null; } $crypted = base64_decode ( $crypted ); $r = openssl_public_decrypt( $crypted , $decrypted , $this ->publicKey); if ( $r === true) { return $decrypted ; } return null; } /** * 构造签名 * @param string $dataString 被签名数据 * @return string */ public function sign( $dataString ) { $signature = false; openssl_sign( $dataString , $signature , $this ->privateKey); return base64_encode ( $signature ); } /** * 验证签名 * @param string $dataString 被签名数据 * @param string $signString 已经签名的字符串 * @return number 1签名正确 0签名错误 */ public function verify( $dataString , $signString ) { $signature = base64_decode ( $signString ); $flg = openssl_verify( $dataString , $signature , $this ->publicKey); return $flg ; } public function __destruct() { is_resource ( $this ->privateKey) && @openssl_free_key( $this ->privateKey); is_resource ( $this ->publicKey) && @openssl_free_key( $this ->publicKey); } } /*$publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKZ1mKTymRoGKnHiP1xAy4aiyt5r0BscCZnDAonCrMFZ4kBGriPNHxEaLr5lfBnMKw7k6i+2dsFPSEZooTvqtPUCAwEAAQ=='; $privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEApnWYpPKZGgYqceI/XEDLhqLK3mvQGxwJmcMCicKswVniQEauI80fERouvmV8GcwrDuTqL7Z2wU9IRmihO+q09QIDAQABAkBunx3nGHXYjppsfn++7iyTd+I7+Agfy/0xWyB3rpEiGGgfemjcRFaeq5SC2vUNXsrEOY5gbUSQmFxH//Cym18NAiEA1z1cZx/Q9cbIjFPwp1a+K5CVFDXDcfbi/AQgAkVs0/cCIQDF+2fr23AoBslcOC4S0yAx94AbgxCntYuRqztxybsrcwIgMW86ZcT87TX2oaQ1xXk6vC68zqN6fBZEE7Wu1Fa1pAkCIElmOJP3qfAc/AAlj+dIwLHlqWgJwl3674CU9Bfui2bDAiEA0CKJpF8x7KANCcopEQC93PsbIztuML322LOfDV1Lw/k='; $rsa = new RSA($publicKey, $privateKey, 1);*/ $publicKeyString = "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1ffL+kUEedBLTzQrKU+ 8oq9IZSUroxhmnWrXa1XMGtlbeVCHQNljujqwGuLELyk7i78cGczwCyGE2SVj9oI tBzGn02fWZNCb3bHPv6ofliTvqYcZOFaFTWB+tTKuOmopCk/bgQVe7HC6+74s/3x Q4tM1jVbNPYSY11++DLjEQ8KaA3pNJwoFTxER3GVEgmfhi5xUTTaBa5ZOIaNfsFr 0fGzvGbmRpqoIor6MlSxXbMO4k2pMzB7YJYYr7zRC28DoeJCj5XnXkq4XPIJzo8/ g79163dp0y9m7cDn4NfRDdBsFeHy6n+hKps6hSVf1z1ZtQtlfk0mRE/EchubDcuH +QIDAQAB ----- END PUBLIC KEY-----"; $privateKeyString = "-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnV98v6RQR50Et PNCspT7yir0hlJSujGGadatdrVcwa2Vt5UIdA2WO6OrAa4sQvKTuLvxwZzPALIYT ZJWP2gi0HMafTZ9Zk0Jvdsc+/qh+WJO+phxk4VoVNYH61Mq46aikKT9uBBV7scLr 7viz/fFDi0zWNVs09hJjXX74MuMRDwpoDek0nCgVPERHcZUSCZ+GLnFRNNoFrlk4 ho1+wWvR8bO8ZuZGmqgiivoyVLFdsw7iTakzMHtglhivvNELbwOh4kKPledeSrhc 8gnOjz+Dv3Xrd2nTL2btwOfg19EN0GwV4fLqf6EqmzqFJV/XPVm1C2V+TSZET8Ry G5sNy4f5AgMBAAECggEAd5rFiV/EmXs4yVVzLEI7OG1S+oJQtmTdieFaZuzyqUfJ Sf+W/lekKb1ts7PpxD+gfiCVCt2oTk1EUu4MO7GxkNIUYF3Ba+tli3dQt0SaNxum FZhyKOQsV4ZT7WxTrFBM2XAlxsMie7M0xx6ZIUR6QTV56IxgMP1DbUOw8UKlqlV2 p3Vdckfjt2pWyLqM2yZUoC3+AjfqpJus/dpyIRGtLd8rLoFCrPgM2naEWxYCAeyI CpHgzYCCAbWyXZOkFOWIFPm53ZDbdZpupzKjS29rYGjiZ7St6sdCegGoZ+aYeUwA Bb1RKZjkBeLrxbuIZHlSbrBO12yE8gZ+VPzgSy1CVQKBgQDWHjj/7Yur/m+d9yJ0 9S14TK5KX3EX2cl46It8FMJEKTk1IhgYB6Dmk10pDrV2glJ3zLfwYeu82p9Zgswh F34mU3o67medJ3OJP+/qHYvEm4WOKw1973v8GEQhqTvr7yPYVC/cRoyN49FKbKfC sF7Scw7EaTObxtWMDJyaa+JDPwKBgQDIE3DhYzx1YahEHktYgVw9OaDdykzYZV2J KO8rkAwS0oXY6yi2J1nCrq3N5Ro7PAMCESRabgAps7n2GazLNfrtG/DcH87M0kYz AEwo1DvI3XVIAjiPmZXBeU2xp1o40OOxZXeHP3VzuU2ydyR6yp3Y2WCClmgf3Vuz O1uGk2A+xwKBgCZzbPcAuJldarvqWoS4Vr8Ivi/a7dtDn/uXfxz8OVq2MHDLO5pt HEbr5cnuu0WZ56dd2xZO71+Nvxn69B9pMZ0+Vm/oyjCdmhDmq3XWcngPGa/LKXQZ IqHF1c5ZrsoSutQpYiLjhHAinj4IPyQmOhD+2oMJBVyPG2A4D5Nnlk1PAoGBAIXH ognC3hEqzGVH0F+Ml82EdBD5DOsA1Es7KLj7J2eKht7lVqJ9q2ImhKaQkzqaRPSj 26fvt4Iq36QzxLtYC8FxllrJlfCUhUXi5AnE53jGw33zpjg2nNDyOEYavZQR8L2U OBkiEHnhpJc5XRYR1vvBVevbgCIWVBODFA7nCkrPAoGAK2oIQ5SLu5OfAB4qcN6v vHERc8JXGZWL/o2Z/4t0OX1X6NwDdAl87LCyQ6ab3dqmgemtjdd2Z9DDn2m9oPtO yuNvlxYNiCqgsNyUCwy6Q1yy1fOvhiUJF8rkq4UTSeQ8gSrf8hf3ajHmzhA1r5B7 Y5MUPUHIS6ckWMTF+pAXAgQ= ----- END PRIVATE KEY-----"; //$rsa = new RSA($publicKeyString, $privateKeyString, 2); $rsa = new RSA( "public.pem" , "private.pem" , 3); echo "私钥加密 公钥解密" ; echo "<br>" ; $s = $rsa ->privEncrypt( "abc" ); echo $rsa ->pubDecrypt( $s ); echo "<br>" ; echo "公钥加密,私钥解密" ; echo "<br>" ; $d = $rsa ->pubEncrypt( "dfg" ); echo $rsa ->privDecrypt( $d ); echo "<br>" ; echo "签名" ; echo "<br>" ; $str = "a=1&b=2" ; $sign = $rsa ->sign( $str ); echo $sign ; $res6 = $rsa ->verify( $str , $sign ); echo "<br>" ; echo "验证签结果:" . $res6 ; |
以上就是PHP三种方式读取RSA密钥加解密、签名验签完整教程的详细内容,更多关于PHP RSA密钥的资料请关注IT俱乐部其它相关文章!