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正则表达式介绍
Aug 06 Python
Python中在for循环中嵌套使用if和else语句的技巧
Jun 20 Python
使用pandas实现csv/excel sheet互相转换的方法
Dec 10 Python
Django重置migrations文件的方法步骤
May 01 Python
python pandas时序处理相关功能详解
Jul 03 Python
详解Python Matplotlib解决绘图X轴值不按数组排序问题
Aug 05 Python
使用 Supervisor 监控 Python3 进程方式
Dec 05 Python
python第三方库学习笔记
Feb 07 Python
基于python实现地址和经纬度转换
May 19 Python
python IP地址转整数
Nov 20 Python
python 动态渲染 mysql 配置文件的示例
Nov 20 Python
python urllib库的使用详解
Apr 13 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设计模式 FlyWeight (享元模式)
2011/06/26 PHP
PHP上传文件时文件过大$_FILES为空的解决方法
2013/11/26 PHP
测试php连接mysql是否成功的代码分享
2014/01/24 PHP
PHP实现事件机制的方法
2015/07/10 PHP
百万级别知乎用户数据抓取与分析之PHP开发
2015/09/28 PHP
javascript 面向对象编程基础:封装
2009/08/21 Javascript
Javascript学习笔记4 Eval函数
2010/01/11 Javascript
jQuery中创建实例与原型继承揭秘
2011/12/21 Javascript
如何制作浮动广告 JavaScript制作浮动广告代码
2012/12/30 Javascript
jQuery中remove()方法用法实例
2014/12/25 Javascript
jQuery中hover方法和toggle方法使用指南
2015/02/27 Javascript
JS+CSS实现精美的二级导航效果代码
2015/09/17 Javascript
BootStrap入门教程(二)之固定的内置样式
2016/09/19 Javascript
从零开始学习Node.js系列教程之SQLite3和MongoDB用法分析
2017/04/13 Javascript
jQuery Plupload上传插件的使用
2017/04/19 jQuery
vue中阻止click事件冒泡,防止触发另一个事件的方法
2018/02/08 Javascript
详解使用VueJS开发项目中的兼容问题
2018/08/02 Javascript
原生JS实现随机点名项目的实例代码
2019/04/30 Javascript
Typescript 中的 interface 和 type 到底有什么区别详解
2019/06/18 Javascript
微信小程序跳转到其他网页(外部链接)的实现方法
2019/09/20 Javascript
JS数组Reduce方法功能与用法实例详解
2020/04/29 Javascript
VUE使用 wx-open-launch-app 组件开发微信打开APP功能
2020/08/11 Javascript
python进阶教程之文本文件的读取和写入
2014/08/29 Python
在Python中操作文件之seek()方法的使用教程
2015/05/24 Python
python pygame实现方向键控制小球
2019/05/17 Python
在python Numpy中求向量和矩阵的范数实例
2019/08/26 Python
python如何将两个txt文件内容合并
2019/10/18 Python
Python+Django+MySQL实现基于Web版的增删改查的示例代码
2020/05/13 Python
Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法
2020/05/26 Python
python3爬虫中多线程进行解锁操作实例
2020/11/25 Python
Python 中 sorted 如何自定义比较逻辑
2021/02/02 Python
英语专业自荐书
2014/06/13 职场文书
社区灵活就业证明
2014/11/03 职场文书
物业工程部主管岗位职责
2015/04/16 职场文书
2015年主婚人婚礼致辞
2015/07/28 职场文书
Java基础之详解HashSet的使用方法
2021/06/30 Java/Android