项目中需要加密超长json内容才发现rsa加密长度有限制,于是换一种思路:我们将原本需要加密的内容拆分为多个字符串,一段一段的加密,解密端也是一段一段的解密即可完成。
(1).确认每次加密多少长度
首先我们要知道rsa加密长度是多少,1024位的rsa能加密的长度也是1024位。那么我们一次加密多长的字符串比较好? 是不是1024/8呢?不是的!因为如果你每次能保证每次要加密的是1024位那就没事这样算是对,但是如果你要加密的字符串不足1024位,不足的部分会用你设置的padding方式去填充这部分内容。那么我们分段加密的长度的公式就是:证书位数/8-padding长度,例如1024的证书配合OPENSSL_PKCS1_PADDING 长度的公式:1024/8-11即可
(2).确认每次解密多少长度
解密不需要考虑填充,所以每次解密大小 = 证书位数/8
class Rsa { const RSA_ENCRYPT_BLOCK_SIZE = 117;//加密切割长度 const RSA_DECRYPT_BLOCK_SIZE = 128;//解密切割长度 /** * @param $private_key私钥 * @return false|resource */ public static function getPrivateKey($private_key) { // $abs_path = base_path().'/public/rsa/rsa_private_key.pem'; //私钥文件方式读取 // $content = file_get_contents($abs_path); // return openssl_pkey_get_private($content); return openssl_pkey_get_private($private_key); } /** * @param $public_key公钥 * @return false|resource */ private static function getPublicKey($public_key) { // $abs_path = base_path().'/public/rsa/rsa_public_key.pem'; //公钥文件方式读取 // $content = file_get_contents($abs_path); // return openssl_pkey_get_public($content); return openssl_pkey_get_public($public_key); } /** * 私钥加密 * @param $private_key私钥字符 * @param string $content 加密字符串 * @return string|null */ public static function privEncrypt($private_key,$content = '') { if (!is_string($content)) { return null; } $result=''; $data = str_split($content, self::RSA_ENCRYPT_BLOCK_SIZE); foreach ($data as $block) { openssl_private_encrypt($block, $dataEncrypt, self::getPrivateKey($private_key), OPENSSL_PKCS1_PADDING); $result .= $dataEncrypt; } return $result ? base64_encode($result) : null; } /** * 公钥加密 * @param $public_key公钥字符 * @param string $content 加密字符串 * @return string|null */ public static function publicEncrypt($public_key, $content = '') { if (!is_string($content)) { return null; } $result=''; $data = str_split($content, self::RSA_ENCRYPT_BLOCK_SIZE); foreach ($data as $block) { openssl_public_encrypt($block, $dataEncrypt, self::getPublicKey($public_key), OPENSSL_PKCS1_PADDING); $result .= $dataEncrypt; } return $result ? base64_encode($result) : null; } /** * 私钥解密 * @param $private_key私钥 * @param string $encrypted解密字符串 * @return string|null */ public static function privDecrypt($private_key,$encrypted = '') { if (!is_string($encrypted)) { return null; } $result = ''; $data = str_split(base64_decode($encrypted), self::RSA_DECRYPT_BLOCK_SIZE); foreach ($data as $block) { openssl_private_decrypt($block, $dataDecrypt, self::getPrivateKey($private_key), OPENSSL_PKCS1_PADDING); $result .= $dataDecrypt; } return $result ? $result : null; } /** * 公钥解密 * @param $public_key公钥 * @param string $encrypted解密字符串 * @return string|null */ public static function publicDecrypt($public_key,$encrypted = '') { if (!is_string($encrypted)) { return null; } $result = ''; $data = str_split(base64_decode($encrypted), self::RSA_DECRYPT_BLOCK_SIZE); foreach ($data as $block) { openssl_public_decrypt($block, $dataDecrypt, self::getPublicKey($public_key), OPENSSL_PKCS1_PADDING); $result .= $dataDecrypt; } return $result ? $result : null; } }