RSA基本介绍、加解密、加验签

学习目标:

  • 公钥与私钥
  • 加密、解密
  • 加签、验签
  • 使用场景
  • 加密、解密代码
  • 加签、验签代码

学习内容:

提示:前面是一些数据概念的表述,后面会举例,进一步说明和使用;

一、概念

RSA加密是一种非对称加密算法。数据传输过程中不进行秘钥的传递。确保了信息的安全性,避免了直接传递秘钥所造成的被破解的风险。与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。

1. 公钥与私钥

公钥:公钥用来给数据加密,用公钥加密的数据只能用私钥解密。
私钥:私钥用来给需要传输的文本的摘要进行加密,获得密文的这个过程也叫做 签名,同理用私钥签名的数据只能用公钥来实现签名验证

2.加密、解密

我们通常所说的加密、解密指的是:公钥加密,私钥解密,加密是为了防止信息被泄漏。

3.加签、验签

通常所说的加签、验签指的是:私钥加签、公钥验签,加签是为了防止信息被篡改。

4.使用场景

网络通信安全、数字签名、身份认证、数据加密等。

举例场景一:聊天

RSA加密的过程
(1)A 生成了一对密钥(公钥和私钥),私钥不公开自己留着,公钥公开 ,发送给所有想发送的人。
(2)A 传递公钥给 B,B用A的公钥,对信息加密,发送给A
(3)A 接收到 B,发送的信息,用A的私钥,解密信息,获取数据。
这个过程,有两次传递,一次是A将公钥传给B,第二次是B将公钥加密后的信息传给A,即使两次均被恶意获取,也没有关系,只有A手中的私钥,可以解密出准确的信息。

场景二:A收到B的信息后,需要回复“收到”,形成闭环

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的私钥,对消息解密获得最终信息。达到既不泄露也不篡改,更能保证信息的安全性。
在这里插入图片描述

RSA加解密、签名验签的代码

rsa双向加密

相关函数

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;

    }
?>
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenSSL是一个开源的加密库,它提供了RSA加密、解密、名和验的功能。 对于RSA加密和解密,我们可以使用OpenSSL提供的命令行工具或者API来实现。 使用命令行工具,我们可以通过以下命令进行RSA加密: openssl rsautl -encrypt -in <input file> -out <output file> -inkey <public key file> -pubin 其中,<input file>是要加密的文件,<output file>是加密后的文件,<public key file>是存储公钥的文件,-pubin参数表示输入的是公钥。 使用命令行工具,我们可以通过以下命令进行RSA解密: openssl rsautl -decrypt -in <input file> -out <output file> -inkey <private key file> 其中,<input file>是要解密的文件,<output file>是解密后的文件,<private key file>是存储私钥的文件。 对于RSA名和验,我们可以使用以下命令进行名: openssl rsautl -sign -in <input file> -out <output file> -inkey <private key file> 其中,<input file>是要名的文件,<output file>是名后的文件,<private key file>是存储私钥的文件。 使用以下命令进行验: openssl rsautl -verify -in <input file> -out <output file> -inkey <public key file> -pubin 其中,<input file>是要验的文件,<output file>是验后的文件,<public key file>是存储公钥的文件,-pubin参数表示输入的是公钥。 使用OpenSSL的API进行RSA加密、解密、名和验的操作也是类似的,我们可以通过调用相应的函数来实现。需要注意的是,API的使用需要在代码中显式引入OpenSSL的头文件和链接OpenSSL的库文件。 总之,OpenSSL提供了便捷的工具和API来实现RSA加密、解密、名和验的功能,无论是命令行工具还是API,都可以选择合适的方式进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值