赞
踩
提示:前面是一些数据概念的表述,后面会举例,进一步说明和使用;
RSA加密是一种非对称加密算法。数据传输过程中不进行秘钥的传递。确保了信息的安全性,避免了直接传递秘钥所造成的被破解的风险。与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。
公钥:公钥用来给数据加密,用公钥加密的数据只能用私钥解密。
私钥:私钥用来给需要传输的文本的摘要进行加密,获得密文的这个过程也叫做 签名
,同理用私钥签名
的数据只能用公钥来实现签名验证
。
我们通常所说的加密、解密指的是:公钥加密,私钥解密,加密是为了防止信息被泄漏。
通常所说的加签、验签指的是:私钥加签、公钥验签,加签是为了防止信息被篡改。
网络通信安全、数字签名、身份认证、数据加密等。
RSA加密的过程
(1)A 生成了一对密钥(公钥和私钥),私钥不公开自己留着,公钥公开 ,发送给所有想发送的人。
(2)A 传递公钥给 B,B用A的公钥,对信息加密,发送给A
(3)A 接收到 B,发送的信息,用A的私钥,解密信息,获取数据。
这个过程,有两次传递,一次是A将公钥传给B,第二次是B将公钥加密后的信息传给A,即使两次均被恶意获取,也没有关系,只有A手中的私钥,可以解密出准确的信息。
RSA签名的过程:
(1)A 生成了一对密钥(公钥和私钥),私钥不公开自己留着,公钥公开 ,所有人可以获取。
(2)A用私钥将要发送的信息进行加签,形成签名,发送给B。
(3)B接收到A发送的信息,获取A的公钥进行验签,如果验签失败证明消息被篡改。
这个过程中也有2次传递,第一次A将私钥加密的信息传递给B,第二次 B 获取 A 的公钥,即使被恶意截获,也没有危险,即使知道了消息的内容,也无法伪造带签名的信息回复给B,因为只有A的私钥才能对信息进行签名,防止了信息被恶意篡改。
但是,综合上边两个场景你会发现,第一个场景虽然被截获但并没有泄漏,但是可以利用截获的公钥,加密假的指令,然后传递给A。第二个场景虽然截获的消息不能被篡改,但是消息的内容,可以利用公钥来获得,并不能防止泄漏。所以在实际应用中,要根据情况使用,也可以同时使用加密和签名,
比如A和B都有一套自己的公钥和秘钥,当 A 要给B发送消息时,先用 B 的 公钥对消息加密,再用A的私钥对消息签名。B在拿到消息后,先用A的公钥对消息验签,确认数据没有被恶意篡改。再用B的私钥,对消息解密获得最终信息。达到既不泄露也不篡改,更能保证信息的安全性。
openssl_public_encrypt()
公钥加密 => openssl_private_decrypt()
私钥解密
openssl_private_encrypt()
私钥加密 => openssl_public_decrypt()
公钥解密
openssl_sign()
私钥加签 => openssl_verify()
公钥验签
openssl_public_encrypt()
公钥加密 => openssl_private_decrypt()
私钥解密
<?php /** * 公钥加密 * @param $data 需要加密数据 * @return string|null * */ define('BAOFOO_ENCRYPT_LEN',50); public function pubEncrypt($data){ if(!is_string($data)){ return null; } $data = json_encode($data,320); $encryptdata= ""; $totalLen = strlen($data); $encryptPos = 0; while($encryptPos < $totalLen){ openssl_public_encrypt(substr($data,$encryptPos,BAOFOO_ENCRYPT_LEN),$encrypted,$publickey); $encryptdata .= base64_encode($encrypted).','; $encryptPos += BAOFOO_ENCRYPT_LEN; } if($encryptdata){ return $encryptdata; } return null; } /** * 秘钥解密 * @param $encrypted 需要解密数据 * @return mixed|null */ public function privDecrypt($encrypted){ if(!is_string($encrypted)){ return null; } $crypto = ''; $crypted = explode(',',substr($encrypted,0,-1)); foreach($crypted as $chunk){ openssl_private_decrypt(base64_decode($chunk),$decrypted,$privatekey); $crypto .= $decrypted; } return $crypto; } ?>
openssl_private_encrypt()
私钥加密 => openssl_public_decrypt()
公钥解密同上不做过多赘述。
注意
:RSA加密中必须考虑到密码长度、明文长度和密文长度问题。明文长度需要小于私钥长度 。而密文长度则等于密钥长度。因此当加密内容长度大于密钥长度时,有效的rsa加解密就需要对内容进行分段。
所以如果要对任意长度的数据进行加密,就需要将数据分段进行注意加密,并将结果进行拼接。同样,解码也需要分段解码,并将结果进行拼接。
<?php /** * 私钥加签 * @param $data 需要加签的数据 * @return string|null */ public function sign($data){ $data = json_encode($data,320); $signdata = ""; $totalLen =strlen($data); $signPos = 0; while($signPos <$totalLen){ openssl_sign(substr($data,$signPos,BAOFOO_ENCRYPT_LEN),$sign,$this->privatekey); $signdata .= base64_encode($sign).','; $signPos += BAOFOO_ENCRYPT_LEN; } return $signdata; } /** * 公钥验证 * @param $data 源数据/hash算法后的值 * @param $sign 签名 * @return bool|null */ public function verify($data,$sign){ $signdata = explode(',',substr($sign,0,-1)); $data = json_encode($data,320); $signPos = 0; $res = ''; foreach($signdata as $chunk){ $res = (bool)openssl_verify(substr($data,$signPos,BAOFOO_ENCRYPT_LEN),base64_decode($chunk),$this->publickey); if(!$res){ return null; } $signPos += BAOFOO_ENCRYPT_LEN; } return $res; } ?>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。