RSA 非对称加密之分段加密

前言:在我们 vip 课的练手项目中涉及到了非对称加密,上课讲了但是部分同学还是不太理解,今天就写个博客来聊一聊非对称加密,希望对大家有帮助。

一、如何区分对称加密还是非对称加密
  1. 对称加密算法在加密和解密时使用的是同一个秘钥;
  2. 非对称加密算法需要两个密钥来进行加密和解密,公钥(public key)和私钥(private key),公钥用于加密私钥用于解密;
二、非对称加密需要使用哪些库
  1. rsa
    pip install rsa==4.8
  2. base64
    python 自带无需安装
三、非对称加密步骤
  1. 生成公钥私钥
  2. 预加密计算模值
  3. 加密/分段加密
四、非对称加密步骤详解
  1. 生成公钥私钥
    方式一:

    import rsa
    #生成秘钥对象,可以直接用,512为秘钥长度
    pubkey,privkey = rsa.newkeys(512)
    

    方式二:

    import rsa
    #保存为xxx.pem格式,这个格式是固定的,不能随便用文档保存
    pubkey = pubkey.save_pkcs1()
    privkey = privkey.save_pkcs1()
    
    #写入文档
    with open(file="pubkey.pem",mode="wb") as pub:
        pub.write(pubkey)
    with open(file="privkey.pem",mode="wb") as pub:
        pub.write(privkey)
    
  2. 预加密计算模值

    #模长计算公式 = 证书key位数/8 - 11
    #证书key位数:一般是512、1024、2048,这个步骤可以问开发,也可以通过加密后密串长度来推算
    #证书key位数:动态获取,加密串长度与证书位数对应关系:{'64':512,'128':1024,"512":2048}
    
    #代码演示
    def choice_channel():
        msg = "test".encode()
        models_dict={'64':512,'128':1024,"512":2048}
        encrypt_msg = rsa.encrypt(message=msg, pub_key=self.pubkey)
        max_decode_len = len(encrypt_msg)
        key_size = models_dict['{}'.format(max_decode_len)]
        max_encode_len = int(key_size/8-11)
        print("加密模长:",max_encode_len)
        return max_encode_len,max_decode_len
    
  3. 加密/分段加密

    import rsa
    import base64
    
    class MyRsa:
        def __init__(self):
            privkey = """
            -----BEGIN RSA PRIVATE KEY-----
            MIIBOwIBAAJBAJBWZJsSrhwDmtjZkq0hsS0ZSa7JJPvo5gfybdHnRLuZa9jGwfBh
            sXFFCJYnZabjQLJ1oPbQ1f7jwbS1WDxI9FkCAwEAAQJABkvuiaFP/SLfH3SmZG0i
            2I/Q2hImTeMEHfaiedS37wjwFCjtK12O73ZviLjtpeFyWHcoqEkAhxTvZZfpGNWs
            vQIjAMrsJdBGRb3IFktM6+JF6aHAsUPp2Py7tYo++R241U/kAm8CHwC2F1jyw0Lb
            o1v/t2dDq6U1/TbpcnfqUI5zzw6HubcCIi2LJM2DCCIZJ0/NOt/1GwOv0NlSQd4v
            bwZRLe5Kzq14mkcCHkmlQ7pbssy2U10nRkKeR2GAmhbszwcbsaGxGsVWHQIiE6tW
            fSyhJt5DtrAhwkbZwRqWFjovii5QSSzuBmFztnt8VA==
            -----END RSA PRIVATE KEY-----
            """
            pubkey = """
            -----BEGIN RSA PUBLIC KEY-----
            MEgCQQCQVmSbEq4cA5rY2ZKtIbEtGUmuyST76OYH8m3R50S7mWvYxsHwYbFxRQiW
            J2Wm40CydaD20NX+48G0tVg8SPRZAgMBAAE=
            -----END RSA PUBLIC KEY-----
            """
            #加载秘钥对象
            self.pubkey =rsa.PublicKey.load_pkcs1(pubkey)
            self.privkey=rsa.PrivateKey.load_pkcs1(privkey)
            #预加密计算模长
            self.max_encode_len,self.max_decode_len = self.choice_channel()
    
        #预加密,获取模长
        def choice_channel(self):
            msg = "test".encode()
            models_dict={'64':512,'128':1024,"512":2048}
            encrypt_msg = rsa.encrypt(message=msg, pub_key=self.pubkey)
            max_decode_len = len(encrypt_msg)
            key_size = models_dict['{}'.format(max_decode_len)]
            max_encode_len = int(key_size/8-11)
            return max_encode_len,max_decode_len
    
        #加密
        def encode_string(self,string):
            msg = string.encode()
            encrypt_msg = rsa.encrypt(message=msg,pub_key=self.pubkey)
            encrypt_msg = base64.b64encode(encrypt_msg)
            encrypt_msg = encrypt_msg.decode()
            return encrypt_msg
    
        #分段加密
        def section_encode(self,msg):
            if len(msg) <= self.max_encode_len:
                print("不需要进行分段加密")
                encode_string = self.encode_string(string=msg)
                print("加密结果:", encode_string)
                return encode_string
            else:
                print("需要分段加密")
                encode_text = []
                for i in range(0,len(msg),self.max_encode_len):
                    #需要加密的字符串进行切片
                    section_text = msg[i:(i+self.max_encode_len)]
                    section_text = section_text.encode()
                    #分段加密
                    encode_str = rsa.encrypt(message=section_text, pub_key=self.pubkey)
                    encode_text.append(encode_str)
                #拼接加密后的bytes数据
                encode_bytes = b"".join(encode_text)
                encode_string = base64.b64encode(s=encode_bytes)
                encode_string = encode_string.decode()
                print("分段加密结果:",encode_string)
                return encode_string
    
    
五、参考文献

Pypi 官方文档:https://stuvel.eu/python-rsa-doc/

回帖
请输入回帖内容 ...