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 01 Python
使用python开发vim插件及心得分享
Nov 04 Python
Python输出9*9乘法表的方法
May 25 Python
python 实现数组list 添加、修改、删除的方法
Apr 04 Python
Django框架视图层URL映射与反向解析实例分析
Jul 29 Python
python 经典数字滤波实例
Dec 16 Python
找Python安装目录,设置环境路径以及在命令行运行python脚本实例
Mar 09 Python
如何实现在jupyter notebook中播放视频(不停地展示图片)
Apr 23 Python
Pycharm连接远程服务器过程图解
Apr 30 Python
python求解汉诺塔游戏
Jul 09 Python
Python3.9.1中使用split()的处理方法(推荐)
Feb 07 Python
Django项目在pycharm新建的步骤方法
Mar 02 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
全国FM电台频率大全 - 28 甘肃省
2020/03/11 无线电
PHP的FTP学习(一)
2006/10/09 PHP
php文本转图片自动换行的方法
2013/03/13 PHP
PHP获取远程图片并保存到本地的方法
2015/05/12 PHP
如何在Laravel5.8中正确地应用Repository设计模式
2019/11/26 PHP
PHP超全局变量实现原理及代码解析
2020/09/01 PHP
深入理解PHP+Mysql分布式事务与解决方案
2020/12/03 PHP
js正确获取元素样式详解
2009/08/07 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
2012/03/15 Javascript
页面回到顶部的三种实现(锚标记,js)
2012/10/01 Javascript
script的async属性以非阻塞的模式加载脚本
2013/01/15 Javascript
js键盘事件的keyCode
2014/07/29 Javascript
JavaScript常用验证函数实例汇总
2014/11/25 Javascript
node.js中的emitter.on方法使用说明
2014/12/10 Javascript
jQuery使用之设置元素样式用法实例
2015/01/19 Javascript
JavaScript中String.match()方法的使用详解
2015/06/06 Javascript
深入解析JavaScript中的数字对象与字符串对象
2015/10/21 Javascript
有关JavaScript中call()和apply() 的一些理解
2016/05/20 Javascript
BootStrap3中模态对话框的使用
2017/01/06 Javascript
基于BootStrap实现简洁注册界面
2017/07/20 Javascript
微信小程序实现的图片保存功能示例
2019/04/24 Javascript
Node.js实现一个HTTP服务器的方法示例
2019/05/13 Javascript
基于js实现数组相邻元素上移下移
2020/05/19 Javascript
addEventListener()和removeEventListener()追加事件和删除追加事件
2020/12/04 Javascript
JavaScript仿京东轮播图效果
2021/02/25 Javascript
跟老齐学Python之for循环语句
2014/10/02 Python
jupyter notebook中美观显示矩阵实例
2020/04/17 Python
Django admin管理工具TabularInline类用法详解
2020/05/14 Python
Python3.7安装PyQt5 运行配置Pycharm的详细教程
2020/10/15 Python
初中毕业生自我评价
2015/03/02 职场文书
班主任工作总结范文
2015/08/13 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
如何利用JavaScript实现二叉搜索树
2021/04/02 Javascript
jackson json序列化实现首字母大写,第二个字母需小写
2021/06/29 Java/Android
关于PHP数组迭代器的使用方法实例
2021/11/17 PHP
Nginx HTTP跳转至HTTPS
2022/05/15 Servers