困扰了两天的问题,终于解决了,ok,现在让我发个博客庆祝一下吧.....(开场不知道说啥),言归正传,现在我来说下我这两天踩得坑,有问题的欢迎留言,互相交流
1.关于RSA加密
RSA加密算法是一种非对称加密算法,非对称,意味着这个算法需要一对秘钥,分为公钥和私钥,公钥私钥都可以进行加密解密,哪个加的密,就必须用这一套的另外一个钥进行解密
RSA加密和MD5加密最大的区别就在于,RSA是可逆的,只要有相应的私钥就可以解开;而MD5是不可逆的,
2.使用场景
第一种用法:公钥加密,私钥解密。
这一种是做为信息加密用的,发送者通过公钥加密信息, 只有持有私钥的人才能解密. 保证了被发送的信息不会被第三方知晓。
第二种用法:私钥签名,公钥验签。
这一种适用于数字签名和验证,A使用自己的私钥,生成数字签名给B发消息,B利用公钥进行验签,确定发送方是否为A。
3.实现方式
openssl提供了对RSA的支持,使用时要注意是否打开了openssl的拓展,并注意以下问题。
注意点: RSA加密的明文长度是有限的,百度之后发现很多人说,明文长度要小于等于秘钥长度-11,然后我仔细去找了一下长度是怎么计算的,可参考下面图片上的内容,(附上链接RSA加密长度说明)
我也是因为这个问题被困扰了两天,于是,我开始在网上找解决办法:加密的时候117个字符加密一次,然后把所有的密文拼接成一个密文;解密的时候需要128个字符解密一下,然后拼接成数据。ok,问题解决,大家可以参照PHP RSA密文过长加密解密 越过1024的解决代码,顺便附上我的代码
<?php
namespace Org\Weixin;
class RSA{
private $pi_key='';//私钥(用于用户加密)
private $pu_key='';//公钥(用于服务端数据解密)
public function __construct(){
$this->pi_key = openssl_pkey_get_private(file_get_contents('./php_private.pem'));//私钥,用于加密
$this->pu_key = openssl_pkey_get_public(file_get_contents('./php_public.pem'));//公钥,用于解密
}
//私钥加密
/*public function PrivateEncrypt($data){
openssl_private_encrypt($data,$encrypted,$this->pi_key);
$encrypted = $this->urlsafe_b64encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
return $encrypted;
}*/
public function PrivateEncrypt($data){
// openssl_private_encrypt($data,$encrypted,$this->pi_key);
$crypto = '';
foreach (str_split($data, 117) as $chunk) {
openssl_private_encrypt($chunk, $encryptData, $this->pi_key);
$crypto .= $encryptData;
}
$encrypted = $this->urlsafe_b64encode($crypto);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
return $encrypted;
}
//加密码时把特殊符号替换成URL可以带的内容
function urlsafe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_',''),$data);
return $data;
}
//解密码时把转换后的符号替换特殊符号
function urlsafe_b64decode($string) {
$data = str_replace(array('-','_'),array('+','/'),$string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
return base64_decode($data);
}
//私钥加密的内容通过公钥可用解密出来
public function PublicDecrypt($encrypted){
// $encrypted = $this->urlsafe_b64decode($encrypted);
$crypto = '';
foreach (str_split($this->urlsafe_b64decode($encrypted), 128) as $chunk) {
openssl_public_decrypt($chunk, $decryptData, $this->pu_key);
$crypto .= $decryptData;
}
//openssl_public_decrypt($encrypted,$decrypted,$this->pu_key);//私钥加密的内容通过公钥可用解密出来
return $crypto;
}
//公钥加密
public function PublicEncrypt($data){
//openssl_public_encrypt($data,$encrypted,$this->pu_key);//公钥加密
$crypto = '';
foreach (str_split($data, 117) as $chunk) {
openssl_public_encrypt($chunk, $encryptData, $this->pu_key);
$crypto .= $encryptData;
}
$encrypted = $this->urlsafe_b64encode($crypto);
return $encrypted;
}
//私钥解密
public function PrivateDecrypt($encrypted)
{
$crypto = '';
foreach (str_split($this->urlsafe_b64decode($encrypted), 128) as $chunk) {
openssl_private_decrypt($chunk, $decryptData, $this->pi_key);
$crypto .= $decryptData;
}
//$encrypted = $this->urlsafe_b64decode($encrypted);
//openssl_private_decrypt($encrypted,$decrypted,$this->pi_key);
return $crypto;
}
}