## RSA密文过长加密解密 越过1024的解决代码 > 什么是RSA加密? [RSA ](https://en.wikipedia.org/wiki/RSA)(详见维基百科)算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法,与 md5 和 sha1 不同,到目前为止,也只有极短的RSA加密被破解。 > 使用场景 * 为移动端(IOS,安卓)编写 API 接口 * 进行支付、真实信息验证等安全性需求较高的通信 * 与其他第三方或合作伙伴进行重要的数据传输,用于外部商户系统和本系统之间报文的安全性验证。 > 生成私钥、公钥 **1、生成原始 RSA 私钥文件** ``` openssl genrsa -out private_key.pem 1024 ``` 说明:生成RSA私钥,`private_key.pem` 为存放私钥的文件名,长度1204 **2、将原始 RSA 私钥转换为 pkcs8 格式** ``` openssl pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out rsa_private_key.pem ``` 说明:把RSA私钥转换成PKCS8格式,转化后的私钥 `rsa_private_key.pem` **3、生成 RSA 公钥** ``` openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem ``` 说明:生成RSA公钥文件` rsa_public_key.pem` **4、最后会有三个文件** ``` λ ls private_key.pem rsa_private_key.pem rsa_public_key.pem ``` 文本打开`rsa_private_key.pem`、`rsa_public_key.pem`,里面存放的是私钥、公钥。商户需要把公钥字符串发给易付宝的业务人员,私钥商户自行保存。 [php-rsa 加密解密](https://segmentfault.com/a/1190000012083428) Rsa 服务器类库 ``` <?php /**.------------------------------------------------------------------------------------------------------------------- * | Github: https://github.com/Tinywan * | Blog: http://www.cnblogs.com/Tinywan * |-------------------------------------------------------------------------------------------------------------------- * | Author: Tinywan(ShaoBo Wan) * | DateTime: 2018/8/30 22:48 * | Mail: 756684177@qq.com * | Desc: php-rsa 加密解密 https://segmentfault.com/a/1190000012083428 * '------------------------------------------------------------------------------------------------------------------*/ namespace app\common\library; class Rsa { /** * @var array 默认配置 */ private $_config = [ 'public_key' => '-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbtLA7lMfUvpBgfgzouiPgcnbL DnEcuCK0gMub/EAEqmr82sl+9tH1iQb1w/hgQLptVRxAuUOa03XqlnG3wkAegtQt 4Q5ZtHSSomE8/5FXJvQfGTCz5RARyM0MiLTMZJGhLdVT6O8uCYIrPRQq7u6NVLs9 6YDmtzX2do/sTsWCAwIDAQAB -----END PUBLIC KEY-----', 'private_key' => '-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQCbtLA7lMfUvpBgfgzouiPgcnbLDnEcuCK0gMub/EAEqmr82sl+ 9tH1iQb1w/hgQLptVRxAuUOa03XqlnG3wkAegtQt4Q5ZtHSSomE8/5FXJvQfGTCz 5RARyM0MiLTMZJGhLdVT6O8uCYIrPRQq7u6NVLs96YDmtzX2do/sTsWCAwIDAQAB AoGAfnO3zCuAPp6k0jiMc1T4XgeXwkDwS8qfJMiUkxHBTAi66q8khSAeU7H9HQsS Y9ktji1YzJeo98xULzgPEpWHS/uhA8VZa16TLy9Yfadn2t+wpWpEJ9ZA4jjEqfQj DDxcUc/pEv5siaE/bU8uls4o2nAiuWnI2n5FGrQa2OziGUECQQDPOh3KD2AOZtEF p7i0yxYXe4dCKwenfw5q7l933RgqMXsVR1EAGzAUdIs71hTye6ibhva+eJRfndoV Jq2IHjOdAkEAwFpOZR8j3Cl4zEk/9D9WEnSa8VWLe76vb7DfgfwkSAhs/f2MNF1I zy9W5tPHRiMzaHNgPBFX9tw2u5QzsgOqHwJAPl3zUTjHZA41okoUIPVuNKsMzjE9 IH/wyuXq/ZwhBbHWpVTNYAbOtZlNvjh0HXZyDDzWTgTkQtKzK+J0H59XUQJARukD vYOdVKx1O9pFGWW/9U3HUPCYWyYQxrwNqX2qYmO4ymmOJj+9d6OcBbxM2i5f5UGj WIGMTBUimEQqSpXPQQJAIkHC2GknUv8HaBRLXxYTIAjj78a0pQT2bYlI6R04AwUZ ljBaUGvvdYJ3CGZ32Xk12Te2fMJj5h/yLyEr8uzpzw== -----END RSA PRIVATE KEY-----', ]; /** * 构造函数 * Rsa constructor. * @param $private_key_filepath * @param $public_key_filepath */ public function __construct($private_key_filepath = null, $public_key_filepath = null) { if(!empty($private_key_filepath) && !empty($public_key_filepath)){ $this->_config['private_key'] = $this->_getContents($private_key_filepath); $this->_config['public_key'] = $this->_getContents($public_key_filepath); } } /** * @uses 获取文件内容 * @param $file_path string * @return bool|string */ private function _getContents($file_path) { file_exists($file_path) or die ('密钥或公钥的文件路径错误'); return file_get_contents($file_path); } /** * @uses 获取私钥 * @return bool|resource */ private function _getPrivateKey() { $private_key = $this->_config['private_key']; return openssl_pkey_get_private($private_key); } /** * @uses 获取公钥 * @return bool|resource */ private function _getPublicKey() { $public_key = $this->_config['public_key']; return openssl_pkey_get_public($public_key); } /** * 私钥加密 (使用公钥解密) * @param string $data * @return null|string */ public function privateEncrypt($data = '', $padding = OPENSSL_PKCS1_PADDING) { if (!is_string($data)) return null; $encrypted = ''; $chunks = str_split($data, 117); foreach ($chunks as $chunk) { $partialEncrypted = ''; $encryptionOk = openssl_private_encrypt($chunk, $partialEncrypted, $this->_getPrivateKey(), $padding); if ($encryptionOk === false) { return null; } $encrypted .= $partialEncrypted; } $encrypted = base64_encode($encrypted); return $encrypted; } /** * 公钥加密(使用私钥解密) * @param string $data 加密字符串 * @param int $padding * @return null|string */ public function publicEncrypt($data = '', $padding = OPENSSL_PKCS1_PADDING) { if (!is_string($data)) return null; $encrypted = ''; $chunks = str_split($data, 117); foreach ($chunks as $chunk) { $partialEncrypted = ''; $encryptionOk = openssl_public_encrypt($chunk, $partialEncrypted, $this->_getPublicKey(), $padding); if ($encryptionOk === false) { return null; } $encrypted .= $partialEncrypted; } $encrypted = base64_encode($encrypted); return $encrypted; } /** * @uses 私钥解密 (使用公钥加密) * @param string $encrypted * @return null */ public function privateDecrypt($encrypted = '') { if (!is_string($encrypted)) return null; $decrypted = ''; $chunks = str_split(base64_decode($encrypted), 128); foreach ($chunks as $chunk) { $partial = ''; $decryptIsTrue = openssl_private_decrypt($chunk, $partial, $this->_getPrivateKey()); if ($decryptIsTrue === false) { return null; } $decrypted .= $partial; } return $decrypted; } /** * 公钥解密 (使用私钥解密) * @param string $encrypted 被解密字符串 * @return null */ public function publicDecrypt($encrypted = '') { if (!is_string($encrypted)) return null; $decrypted = ''; $chunks = str_split(base64_decode($encrypted), 128); foreach ($chunks as $chunk) { $partial = ''; $decryptIsTrue = openssl_public_decrypt($chunk, $partial, $this->_getPublicKey()); if ($decryptIsTrue === false) { return null; } $decrypted .= $partial; } return $decrypted; } /** * 私钥验签 * @param $data string 验签内容 * @param $signature string 签名字符串 * @param int $signature_alg * @return bool */ public function privateSign($data, $signature, $signature_alg = OPENSSL_ALGO_SHA1) { $result = openssl_sign($data, base64_decode($signature), $this->_getPrivateKey(), $signature_alg); openssl_free_key($this->_getPrivateKey()); return $result === 1 ? true : false; } /** * 公钥验签 * @param $data string 验签内容 * @param $signature string 签名字符串 * @param int $signature_alg * @return bool */ public function publicSign($data, $signature, $signature_alg = OPENSSL_ALGO_SHA1) { $result = openssl_verify($data, base64_decode($signature), $this->_getPublicKey(), $signature_alg); openssl_free_key($this->_getPublicKey()); return $result === 1 ? true : false; } } ``` > 使用案例 * 公钥加密、私钥解密 ``` $rsa = new Rsa(); // 加密明文 $crypt_text = '公钥加密、私钥解密'; echo '加密明文:' . $crypt_text.PHP_EOL; $public_encrypt_data = $rsa->publicEncrypt($crypt_text); echo '公钥加密后数据:' . $public_encrypt_data.PHP_EOL; // 一直在变化 $private_decrypt_data = $rsa->privateDecrypt($public_encrypt_data); echo '私钥解密数据: ' . $private_decrypt_data.PHP_EOL; ``` >加密明文:公钥加密、私钥解密 >>公钥加密后数据:QHdj15P6l1gJbjNlD7spKT7KjCJJ0Qg5c8JjLBAS9hvhkq8eRuaNY/dDrboD3t40NvyPI8SBFBkDTjJ5IDyqTTSfthUROvasMD7wCPRYGaOt5to+ygfvV5t4CyYQEvSSflqimWvffRs0L8fs3pqE2kLD/AHOC94+ZBNFfzTTtVA= >>>私钥解密数据: 公钥加密、私钥解密 * 私钥加密、公钥解密 ``` $rsa = new Rsa(); // 加密明文 $crypt_text = '私钥加密、公钥解密'; echo '加密明文:' . $crypt_text.PHP_EOL; $private_encrypt_data = $rsa->privateEncrypt($crypt_text); echo '私钥加密后数据:' . $private_encrypt_data..PHP_EOL; // 不变 $public_decrypt_data = $rsa->publicDecrypt($private_encrypt_data); echo '公钥解密数据: ' . $public_decrypt_data..PHP_EOL; ``` > 加密明文:私钥加密、公钥解密 >>私钥加密后数据:dDzAs7kj9z7kS7Zbcz6sNLP+sIOnXp2qFGr4RepZcZp9XzCt8Tt+Kd/NIo4S20hjAvBiurvSHaR6LLL5ur5dc4vkFGkV+bGaT2SlhC4JkvYt4N2T9EiQupwcCtlk+dcENLexWiCvZtuzk3peK+H7AUWqFeOlmGRZb3De7bP+heY= >>>公钥解密数据: 私钥加密、公钥解密 * 测试结果:`私钥加密`是不变的,`公钥加密`后的字符串一直是变化的 > 经历 二流院校,计算机工科男 > 常用ID Tinywan > 主页 [https://www.tinywan.com](https://www.tinywan.com/ ) > GitHub: [https://github.com/Tinywan ](https://github.com/Tinywan ) >博客园地址 [http://www.cnblogs.com/Tinywan](http://www.cnblogs.com/Tinywan)