Python如何基于rsa模块实现非对称加密与解密


Posted in Python onJanuary 03, 2020

这篇文章主要介绍了Python如何基于rsa模块实现非对称加密与解密,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

1、简单介绍:

RSA加密算法是一种非对称加密算法 是由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。

RSA密钥至少为500位长,一般推荐使用1024位。RSA密钥长度随着保密级别提高,增加很快。

由于RSA的特性,一个1024位的密钥只能加密117位字节数据,当数据量超过117位字节的时候,程序就会抛出异常。 ——来自大佬

2、代码实现:

来一段大佬的代码:

import rsa


# 一、生成公钥及私钥, 并保存
public_key, private_key = rsa.newkeys(1024) # 生成公钥和私钥
# 将生成的公钥和私钥进行转换,以便存储
pub = public_key.save_pkcs1()
pri = private_key.save_pkcs1('PEM') # save_pkcsl()是内置方法,其默认参数是‘PEM'
with open('pubkey.pem', mode='wb') as f, open('privkey.pem', mode='wb') as f1:
  f.write(pub) # 打开两个文件,分别存储公钥及私钥
  f1.write(pri)


# 二. 使用公钥加密, 私钥解密
def func():
  with open('pubkey.pem', mode='rb') as f, open('privkey.pem', 'rb') as f1:
    pub = f.read() # 从文件中再读出公钥和私钥
    pri = f1.read()
    public_key = rsa.PublicKey.load_pkcs1(pub) # 转换为原始状态
    private_key = rsa.PrivateKey.load_pkcs1(pri)
  message = "rsa加密测试"
  info = rsa.encrypt(message.encode('utf-8'), public_key) # 使用公钥加密内容,内容必须是二进制
  msg = rsa.decrypt(info, private_key) # 使用私钥解密,获得解密后的内容
  print(msg.decode('utf-8')) # 使用之前记得先解码

3、代码升级:

现在我将上述的代码段封装成一个Rsa class(包含的方法有:__init__——初始化方法,key_transform_store——存储公钥与私钥的方法、encry——加密方法、decry——解密方法),使用的时候,直接将下面的代码段拎到我们需要的地方去引用:先创建一Rsa对象,然后调用里面的方法即可:

import rsa


class Rsa(object):
  """RSA加密、解密"""

  def __init__(self, number, pub_path='public_key.pem', priv_path='private_key.pem'):
    """

    :param pub_path: the path to public key, default its path is public_key.pem
    :param priv_path: the path to private key, default its path is private_key.pem
    """
    # Generate the public and private keys, and returns them
    self.public_key, self.private_key = rsa.newkeys(number)

    self.public_key_path = pub_path
    self.private_key_path = priv_path

  def key_transform_store(self):
    """
    convert and save the generated public and private keys to a file
    :return: None
    """
    # convert the generated public and private keys for storage
    pub = self.public_key.save_pkcs1()
    pri = self.private_key.save_pkcs1('PEM')

    # open two files to store the public key and private key respectively
    
    with open(self.public_key_path, mode='wb') as f:
      f.write(pub)

    with open(self.private_key_path, mode='wb') as f1:
      f1.write(pri)

  def encry(self, info):
    """
    encrypt information
    :param info: the original string information to be encrypted
    :return:info_encrypted
    """
    # read the public key from the file
    with open(self.public_key_path, mode='rb') as f:
      pub = f.read()
      # convert pub to original state
      public_key = rsa.PublicKey.load_pkcs1(pub)

    # use the public key to encrypt the content, which must be binary
    info_encrypted = rsa.encrypt(info.encode('utf-8'), public_key)
    return info_encrypted

  def decry(self, info_encrypted):
    """
    decrypt information
    :param info_encrypted: encrypted information
    :return: info
    """
    # read the private key from the file
    with open(self.private_key_path, 'rb') as f:
      pri = f.read()
      # convert pri to original state
      private_key = rsa.PrivateKey.load_pkcs1(pri)

    # decrypt with private key to obtain the decrypted content
    msg = rsa.decrypt(info_encrypted, private_key)
    info = msg.decode('utf-8') # decode
    return info


rsa_obj = Rsa(1024) # 实例化
rsa_obj.key_transform_store() # 
info_encrypted = rsa_obj.encry('我是真心喜欢你的。') # 加密
print(info_encrypted)
info = rsa_obj.decry(info_encrypted) # 解密
print(info) # 我是真心喜欢你的。

这里会出现一个问题:由于RSA的特性,一个1024位的密钥只能加密117位字节数据,当数据量超过117位字节的时候,程序就会抛出异常。如下测试会抛出:

OverflowError: 189 bytes needed for message, but there is only space for 117

rsa_obj = Rsa(1024) # 实例化
rsa_obj.key_transform_store() # 
info_encrypted = rsa_obj.encry('我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。我是真心喜欢你的。') # 加密
print(info_encrypted)
info = rsa_obj.decry(info_encrypted) # 解密
print(info)

后记: 通常使用中, 会先对数据进行bas64加密, 再对加密后的内容使用rsa加密, 最后对rsa解密后的内容进行bas64解密。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
深入理解Python单元测试unittest的使用示例
Nov 18 Python
Python tkinter事件高级用法实例
Jan 31 Python
python线程池threadpool实现篇
Apr 27 Python
python 3.6.5 安装配置方法图文教程
Sep 18 Python
Django使用paginator插件实现翻页功能的实例
Oct 24 Python
使用python根据端口号关闭进程的方法
Nov 06 Python
Python 利用pydub库操作音频文件的方法
Jan 09 Python
python语言元素知识点详解
May 15 Python
python flask web服务实现更换默认端口和IP的方法
Jul 26 Python
python中bytes和str类型的区别
Oct 21 Python
Python3 虚拟开发环境搭建过程(图文详解)
Jan 06 Python
VSCode配合pipenv搞定虚拟环境的实现方法
May 17 Python
PyTorch的自适应池化Adaptive Pooling实例
Jan 03 #Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
Jan 03 #Python
pytorch AvgPool2d函数使用详解
Jan 03 #Python
使用pyhon绘图比较两个手机屏幕大小(实例代码)
Jan 03 #Python
Python基础之函数原理与应用实例详解
Jan 03 #Python
对Pytorch中Tensor的各种池化操作解析
Jan 03 #Python
Python基础之高级变量类型实例详解
Jan 03 #Python
You might like
PHP中通过语义URL防止网站被攻击的方法分享
2011/09/08 PHP
变量在 PHP7 内部的实现(二)
2015/12/21 PHP
PHP中模拟链表和链表的基本操作示例
2016/02/27 PHP
JS+CSS实现一个气泡提示框
2013/08/18 Javascript
JQuery插件开发示例代码
2013/11/06 Javascript
jquery 为a标签绑定click事件示例代码
2014/06/23 Javascript
javascript 面向对象封装与继承
2014/11/27 Javascript
js实现登陆遮罩效果的方法
2015/07/28 Javascript
5种JavaScript脚本加载的方式
2017/01/16 Javascript
js常用DOM方法详解
2017/02/04 Javascript
angular $watch 一个变量的变化(实例讲解)
2017/08/02 Javascript
浅谈从React渲染流程分析Diff算法
2018/09/08 Javascript
微信JS-SDK updateAppMessageShareData安卓不能自定义分享详解
2019/03/29 Javascript
详解Vue中的scoped及穿透方法
2019/04/18 Javascript
[01:34]完美“圣”典宣传片震撼发布,12.17与你不见不散
2016/12/16 DOTA
[01:29:17]RNG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
python使用arcpy.mapping模块批量出图
2017/03/06 Python
Python多线程threading和multiprocessing模块实例解析
2018/01/29 Python
TensorFlow实现模型评估
2018/09/07 Python
Opencv+Python 色彩通道拆分及合并的示例
2018/12/08 Python
python如何处理程序无法打开
2020/06/16 Python
Python如何读取、写入JSON数据
2020/07/28 Python
Python+unittest+requests 接口自动化测试框架搭建教程
2020/10/09 Python
python基于opencv实现人脸识别
2021/01/04 Python
澳洲小众品牌的集合网站:BNKR
2018/02/23 全球购物
Paul’s Boutique官网:英国时尚手袋品牌
2018/03/31 全球购物
Chicco婴儿用品美国官网:汽车座椅、婴儿推车、高脚椅等
2018/11/05 全球购物
Coccinelle官网:意大利的著名皮具品牌
2019/05/15 全球购物
毕业生自我推荐
2013/11/04 职场文书
企业贷款委托书格式
2014/09/12 职场文书
幼儿教师年度个人总结
2015/02/05 职场文书
龙潭大峡谷导游词
2015/02/10 职场文书
小学语文教师研修日志
2015/11/13 职场文书
HashMap实现保存两个key相同的数据
2021/06/30 Java/Android
修改并编译golang源码的操作步骤
2021/07/25 Golang
Python序列化模块JSON与Pickle
2022/06/05 Python