准备:
首先需要php开启openssl扩展和生成秘钥。
这里没有用函数生成秘钥,直接使用的工具更加方便(函数的话使用openssl_sign和openssl_verify函数);生成秘钥工具使用的是支付宝的RSA签名验签工具。
RSA签名验签工具地址:https://opendocs.alipay.com/open/291/105971
生成秘钥文件
按图中选项生成秘钥文件,保存至对应的文件:
私钥文件格式:
-----BEGIN PRIVATE KEY----- MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJs5xLh3Lt0IT16G8QQd29U9POlDBc/QFv2XkBE9EltwtBnKq75jy+dikPl+5axHKsQcOXnk0FIQerGKWWwbPvVQ4EU7MkORK2KOyhvV44fY6QB8mVsEJN04ptlpFcrKIQ0mNtulCzgAeJoUK27dxhUdLJK7ze2QWs2jEGPrz7utAgMBAAECgYBSr/hCB4MYTVfyU9HJzpoPQprS61gKNqA4oGcnN7Ays5vM7XCFcCXrcU8nCNkR56s5YoufiisKvCqPrtIpy23CbdJcxjJvmGtWh+7hFOR4G8jAttIPAxMxYjjcNq9BhKIWcrrRlk6SHamowHCz2W8c3p8cXtpbdUTg8rhCYNdFxQJBAMs1XJ/mATJTjsPZaAT2/3Em5gZTTyVZDn7qb0eitDX+lUaqEbfGHxIILDEZTmLrHwXqTEPC8roZwjd3CEArnlsCQQDDjT/3ku+CaIVm1ds/OM16y6eO3rRfbc2lAQaPY4a29EytIHMgQS+S46BnIFJBPaGJaSlwJ5c1Bb3ZISnMaDyXAkBdaSQw5Jv8NGjWIqQsVBZMP2NR2Q3yzyNYuA97UJGimGqqVxdZ8RrrQRJ/Z3CfDBHwuClipMTLQ3gB4xfJ18MtAkBNhSUig8EmtUCM76ImgeITF8CoxmhCnEi1bJ6pIQ86X8Y1q3N4Cd9OH6Zqu0lgS4pJ6sJej5NFla0Y8iibu4apAkAd1NYXY9v6wFcZJEPg6giSUkZPKW4fbUwZrRUvVMcW98uGncWfLbaKQ8NY3CL0m7qu8BJ9nQxsDZlzVC+mwxuY -----END PRIVATE KEY-----
公钥文件格式:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbOcS4dy7dCE9ehvEEHdvVPTzpQwXP0Bb9l5ARPRJbcLQZyqu+Y8vnYpD5fuWsRyrEHDl55NBSEHqxillsGz71UOBFOzJDkStijsob1eOH2OkAfJlbBCTdOKbZaRXKyiENJjbbpQs4AHiaFCtu3cYVHSySu83tkFrNoxBj68+7rQIDAQAB -----END PUBLIC KEY-----
加密解密类
<?php class RSAUtils { private $privateKey; private $publicKey; public function __construct() { $this->privateKey = openssl_pkey_get_private( file_get_contents( './private.pem' ) ); $this->publicKey = openssl_pkey_get_public( file_get_contents( './public.pem' ) ); @( $this->privateKey && $this->publicKey ) or die( '密钥或者公钥不可用' ); } //私钥加密,需要公钥解密 public function PrivateEncrypt( $str ) { $crypto = ''; foreach ( str_split( $str, 117 ) as $chunk ) { $encryptData = ''; openssl_private_encrypt( $chunk, $encryptData, $this->privateKey ); $crypto .= $encryptData; } //加密后的内容会乱码,最好转码 return base64_encode($crypto); } //公钥解密私钥加密后的内容 public function PublicDecrypt( $str ) { $crypto = ''; foreach ( str_split( base64_decode( $str ), 128 ) as $chunk ) { $decryptData = ''; openssl_public_decrypt( $chunk, $decryptData, $this->publicKey ); $crypto .= $decryptData; } return $crypto; } //公钥加密,需要私钥解密 public function PublicEncrypt( $str ) { $crypto = ''; foreach ( str_split( $str, 117 ) as $chunk ) { $encryptData = ''; openssl_public_encrypt( $chunk, $encryptData, $this->publicKey ); $crypto .= $encryptData; } //加密后的内容会乱码,最好转码 return base64_encode($crypto); } //私钥解密公钥加密后的内容 public function PrivateDecrypt( $str ) { $crypto = ''; foreach ( str_split( base64_decode( $str ), 128 ) as $chunk ) { $decryptData = ''; openssl_private_decrypt( $chunk, $decryptData, $this->privateKey ); $crypto .= $decryptData; } return $crypto; } }
注意:公钥加密的内容只能用私钥解,反之私钥加密的只能公钥解
另外,公钥加密私钥解密是非对称加解密,意思是每次加密同一内容的结果会不一样,这篇文章有详细讲到:https://blog.csdn.net/guyongqiangx/article/details/74930951