PHP使用openssl进行Rsa加密,如果要加密的明文太长则会出错,解决方法:加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文;解密的时候需要128个字符解密一下,然后拼接成数据。
加密:
/**
* 加密
* @param $originalData
* @return string|void
*/
/*function encrypt($originalData){
// if (openssl_private_encrypt($originalData, $encryptData, $this->rsaPrivateKey)) {
if (openssl_public_encrypt($originalData, $encryptData, $this->rsaPublicKey)) {
return base64_encode($encryptData);
} else {
return false;
}
}*/
function encrypt($originalData){
$crypto = '';
foreach (str_split($originalData, 117) as $chunk) {
openssl_public_encrypt($chunk, $encryptData, $this->rsaPublicKey);
$crypto .= $encryptData;
}
return base64_encode($crypto);
}
解密:
/**
* 私钥解密
* @param $encryptData
*/
/*function decrypt($encryptData){
// if (openssl_public_decrypt(base64_decode($encryptData), $decryptData, $this->rsaPublicKey)) {
if (openssl_private_decrypt(base64_decode($encryptData), $decryptData, $this->rsaPrivateKey)) {
return $decryptData;
} else {
return false;
}
}*/
function decrypt($encryptData){
$crypto = '';
foreach (str_split(base64_decode($encryptData), 128) as $chunk) {
openssl_private_decrypt($chunk, $decryptData, $this->rsaPrivateKey);
$crypto .= $decryptData;
}
return $crypto;
}
也可以使用如下方法:
加密:
function encrypt($data, $rsa_publickey){
$split = str_split($data, 117); // 1024 bit && OPENSSL_PKCS1_PADDING 不大于117即可
$crypto = '';
foreach ($split as $chunk) {
$isOkay = openssl_public_encrypt($chunk, $encryptData, $rsa_publickey);
if(!$isOkay){
return false;
}
$crypto .= base64_encode($encryptData);
}
return $crypto;
}
解密:
function decrypt($data, $rsa_privatekey){
$split = str_split($data, 172); // 1024 bit 固定172
$crypto = '';
foreach ($split as $chunk) {
$isOkay = openssl_private_decrypt(base64_decode($chunk), $decryptData, $rsa_privatekey); // base64在这里使用,因为172字节是一组,是encode来的
if(!$isOkay){
return false;
}
$crypto .= $decryptData;
}
return $crypto;
}
借用网上查到的一段比较详细的解释:
RSA加密解密有个填充方式padding的参数,不同编程语言之间交互,需要注意这个。
padding can be one of OPENSSL_PKCS1_PADDING, OPENSSL_SSLV23_PADDING, OPENSSL_PKCS1_OAEP_PADDING,OPENSSL_NO_PADDING
值得注意的是,如果选择密钥是1024bit长的(openssl genrsa -out rsa_private_key.pem 1024),那么支持加密的明文长度字节最多只能是1024/8=128byte;
如果加密的padding填充方式选择的是OPENSSL_PKCS1_PADDING(这个要占用11个字节),那么明文长度最多只能就是128-11=117字节。如果超出,那么这些openssl加解密函数会返回false。
这时有个解决办法,把需要加密的源字符串按少于117个长度分开为几组,在解密的时候以172个字节分为几组。
其中的『少于117』(只要不大于117即可)和『172』两个数字是怎么来的,值得一说。
为什么少于117就行,因为rsa encrypt后的字节长度是固定的,就是密钥长1024bit/8=128byte。因此只要encrypt不返回false,即只要不大于117个字节,那么返回加密后的都是128byte。
172是因为什么?因为128个字节base64_encode后的长度固定是172。
这里顺便普及下base64_encode。encode的长度是和原文长度有个计算公式:
$len2 = $len1%3 >0 ? (floor($len1/3)*4 + 4) : ($len1*4/3);
参考:
https://www.cnblogs.com/firstForEver/p/5803940.html
https://www.cnblogs.com/CraryPrimitiveMan/p/6242167.html?utm_source=itdadao&utm_medium=referral
Author:leedaning
本文地址:http://blog.csdn.net/leedaning/article/details/51780511
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。