python中的RSA加密与解密实例解析


Posted in Python onNovember 18, 2019

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

什么是RSA:

RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。

正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。

SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。RSA密钥长度随着保密级别提高,增加很快。下表列出了对同一安全级别所对应的密钥长度。

python实现对RSA的加密和解密

Python密码库--Pycrypto

Python良好的生态,对于加密解密技术都有成熟的第三方库。大名鼎鼎的M2Crypto和Pycrypto,前者非常容易使用,可是安装却非常头疼,不同的系统依赖软件的版本还有影响。后者则比较方面,直接使用pip安装即可。

密码技术

为了进行加密以及通信,人们发明了很多公开的算法。对称与非对称算法等。常见的加密方式有RSA, AES等算法。对于选择加密算法,一个常识就是使用公开的算法。一方面是这些算法经过实践检验,另一方面对于破译难度和破译条件破译时间都有预估。对于任何加密算法,都是能破解的,不同在于时间上的投入。

Python密码库--Pycrypto

Python良好的生态,对于加密解密技术都有成熟的第三方库。大名鼎鼎的M2Crypto和Pycrypto,前者非常容易使用,可是安装却非常头疼,不同的系统依赖软件的版本还有影响。后者则比较方面,直接使用pip安装即可。

安装

pip install pycrypto

RSA 密码算法与签名

RSA是一种公钥密码算法,RSA的密文是对代码明文的数字的 E 次方求mod N 的结果。也就是将明文和自己做E次乘法,然后再将其结果除以 N 求余数,余数就是密文。RSA是一个简洁的加密算法。E 和 N 的组合就是公钥(public key)。

对于RSA的解密,即密文的数字的 D 次方求mod N 即可,即密文和自己做 D 次乘法,再对结果除以 N 求余数即可得到明文。D 和 N 的组合就是私钥(private key)。

算法的加密和解密还是很简单的,可是公钥和私钥的生成算法却不是随意的。本文在于使用,对生成秘钥对的算法就暂时忽略。使用 Pycrypto生成秘钥对很简单,我们分别为 Server和Client各生成一对属于自己的秘钥对。

from Crypto import Random
from Crypto.Hash import SHA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.Signature import PKCS1_v1_5 as Signature_pkcs1_v1_5
from Crypto.PublicKey import RSA
 
# 伪随机数生成器
random_generator = Random.new().read
# rsa算法生成实例
rsa = RSA.generate(1024, random_generator)
 
# Server的秘钥对的生成
private_pem = rsa.exportKey()
with open("server-private.pem", "w") as f:
 f.write(private_pem)
 
public_pem = rsa.publickey().exportKey()
with open("server-public.pem", "w") as f:
 f.write(public_pem)
 
# Client的秘钥对的生成
private_pem = rsa.exportKey()
with open("client-private.pem", "w") as f:
 f.write(private_pem)
 
public_pem = rsa.publickey().exportKey()
with open("client-public.pem", "w") as f:
 f.write(public_pem)

所生成的私钥和公钥大概是这样的:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC26X6A0WCWiVxdxq3jtm42yDdGbf+99v2zyi0UMVGZfowlnkcW
eMvpz8NBm2UVlrjZpnFr8wFkdHyjFFkq/ilclH3AN4+Xw8Ap7CGJ2jVMyS5h9RRB
Uyf3F4D5Og8789Ywh9HXYyvD/6J62EtbbkhGPxg3aa8n2kfKZ9N6Q7DqrwIDAQAB
AoGBAJn5qu1D1FxE24Vxl7ZGPzdMigN227+NaPptak9CSR++gLm2KL+JBpcXt5XF
+20WCRvnWjl2QijPSpB5s6pWdHezEa1cl6WrqB1jDJd1U99WNCL5+nfEVD9IF+uE
ig0pnj+wAT5fu78Z0UjxD9307f9S7BLC8ou3dWVkIqob6W95AkEAuPGTNlTkquu/
wBJTb4/+/2ZCf7Ci9qvsN3+RcrzFkKa3uTtBOa6Xk2R61zBkucUgY6cQHPbxhFLN
TVmXdbwxTQJBAP0wGenVOq4dCPdz3NhyghkKT6SL2w/SgbrROiJ1mG9MoBq58/0g
k85I91R7nuvOYTKTUkhWdPYITpDarmPJzesCQGRBmOMgHCHH0NfHV3Gn5rz+61eb
IoyD4Hapceh4CsWCiyAfzhj9229sTecvdbr68Lb0zphVCdIIrQCca63IShUCQGYI
e3jzmHlQdCudArQruWgz8pKiVf7TW7qY1O/MKkk4PRFoPP6WoVoxp5LhWtM20Y7b
Nf628N2xzU+tAThvvE8CQQCI1C7GO3I5EMfqPbTSq2oZq8thvGlyFyI7SNNuvAHj
hj2+0217B9CcTZqloYln01CNDVuaoUgEvFSw1OdRB1tC
-----END RSA PRIVATE KEY-----
 
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC26X6A0WCWiVxdxq3jtm42yDdG
bf+99v2zyi0UMVGZfowlnkcWeMvpz8NBm2UVlrjZpnFr8wFkdHyjFFkq/ilclH3A
N4+Xw8Ap7CGJ2jVMyS5h9RRBUyf3F4D5Og8789Ywh9HXYyvD/6J62EtbbkhGPxg3
aa8n2kfKZ9N6Q7DqrwIDAQAB
-----END PUBLIC KEY-----

加密与解密

通常通信的时候,发送者使用接受者的公钥加密,接受者使用接受者私钥解密。

简而言之,Server给Client通信,需要加密内容,那么Client会生成一个秘钥对,Client的公钥client-public.pem和私钥client-private.pem 。Client把公钥公开给发送者,任何人都可以用来加密,然后Server使用client-public.pem进行加密,然后把内容发给Client,Client再使用私钥client-private.pem进行解密。

1.加密(encrypt)

# Server使用Client的公钥对内容进行rsa 加密
 
message = "hello client, this is a message"
with open("client-public.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  cipher = Cipher_pkcs1_v1_5.new(rsakey)
  cipher_text = base64.b64encode(cipher.encrypt(message.encode('utf-8')))
  print(cipher_text.decode('utf-8'))
 
#加密结果:
HYQPGB+axWCbPp7PPGNTJEAhVPW0TX5ftvUN2v40ChBLB1pS+PVM3YGT5vfcsvmPZhW8NKVSBp8FwjLUnMn6yXP1O36NaunUzyHwI+cpjlkTwZs3DfCY/32EzeuKuJABin1FHBYUMTOKtHy+eEDOuaJTnZTC7ZBkdha+J88HXSc=

cipher_text 即 Master加密后将要发送给Client的密文。

2.解密(decrypt)

# Client使用自己的私钥对内容进行rsa 解密
 
with open("client-private.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  cipher = Cipher_pkcs1_v1_5.new(rsakey)
  text = cipher.decrypt(base64.b64decode(encrypt_text), random_generator)
  print(text.decode('utf-8'))
 
#解密结果:
hello client, this is a message

这样Client就能看到Server所发的内容了,当然,如果Client想要给Server发消息,就需要Server先把其的公钥给Client,后者再使用公钥加密,然后发送给Server,最后Server使用自己的私钥解密。

签名与验签

当然,对于窃听者,有时候也可以对伪造Server给Client发送内容。为此出现了数字签名。也就是Server给Client发送消息的时候,先对消息进行签名,表明自己的身份,并且这个签名无法伪造。具体过程即Server使用自己的私钥对内容签名,然后Client使用Server的公钥进行验签。

签名

# Server使用自己的私钥对内容进行签名
 with open("server-private.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  signer = Signature_pkcs1_v1_5.new(rsakey)
  digest = SHA.new()
  digest.update(message)
  sign = signer.sign(digest)
  signature = base64.b64encode(sign)
  print signature
 
#签名结果:
jVUcAYfgF5Pwlpgrct3IlCX7KezWqNI5tD5OIFTrfCOQgfyCrOkN+/gRLsMiSDOHhFPj2LnfY4Cr5u4eG2IiH8+uSF5z4gUX48AqCQlqiOTLk2EGvyp+w+iYo2Bso1MUi424Ebkx7SnuJwLiPqNzIBLfEZLA3ov69aDArh6hQiw=

验签

#Client使用Server的公钥对内容进行验签
 
with open("server-public.pem") as f:
  key = f.read()
  rsakey = RSA.importKey(key)
  verifier = Signature_pkcs1_v1_5.new(rsakey)
  digest = SHA.new()
  # Assumes the data is base64 encoded to begin with
  digest.update(message)
  is_verify = signer.verify(digest, base64.b64decode(signature))
  print is_verify
#验签结果:
True

总结

Pycrypto提供了比较完善的加密算法。RSA广泛用于加密与解密,还有数字签名通信领域。使用Publick/Private秘钥算法中,加密主要用对方的公钥,解密用自己的私钥。签名用自己的私钥,验签用对方的公钥。

  • 加密解密:公钥加密,私钥解密
  • 签名验签:私钥签名,公钥验签

无论是加密解密还是签名验签都使用同一对秘钥对。

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

Python 相关文章推荐
Python处理RSS、ATOM模块FEEDPARSER介绍
Feb 18 Python
python类和函数中使用静态变量的方法
May 09 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
Apr 05 Python
用python的requests第三方模块抓取王者荣耀所有英雄的皮肤实例
Dec 14 Python
批量将ppt转换为pdf的Python代码 只要27行!
Feb 26 Python
python 获取指定文件夹下所有文件名称并写入列表的实例
Apr 23 Python
python join方法使用详解
Jul 30 Python
Django之PopUp的具体实现方法
Aug 31 Python
tensorflow实现打印ckpt模型保存下的变量名称及变量值
Jan 04 Python
Python3基于plotly模块保存图片表格
Aug 03 Python
python 如何利用argparse解析命令行参数
Sep 11 Python
python ConfigParser库的使用及遇到的坑
Feb 12 Python
wxpython绘制圆角窗体
Nov 18 #Python
wxpython绘制音频效果
Nov 18 #Python
python导入不同目录下的自定义模块过程解析
Nov 18 #Python
解决django model修改添加字段报错的问题
Nov 18 #Python
python sorted方法和列表使用解析
Nov 18 #Python
在Django中实现添加user到group并查看
Nov 18 #Python
Django继承自带user表并重写的例子
Nov 18 #Python
You might like
用php实现百度网盘图片直链的代码分享
2012/11/01 PHP
常用参考资料(手册)下载或者链接
2006/07/22 Javascript
一个JS翻页效果
2007/07/23 Javascript
JQUERY CHECKBOX全选,取消全选,反选方法三
2008/08/30 Javascript
AJAX使用了UpdatePanel后无法使用alert弹出脚本
2010/04/02 Javascript
JQuery中each()的使用方法说明
2010/08/19 Javascript
25个好玩的JavaScript小游戏分享
2011/04/22 Javascript
js querySelector和getElementById通过id获取元素的区别
2012/04/20 Javascript
对frameset、frame、iframe的js操作示例代码
2013/08/16 Javascript
浏览器兼容console对象的简要解决方案分享
2013/10/24 Javascript
jQuery团购倒计时特效实现方法
2015/05/07 Javascript
JS & JQuery 动态添加 select option
2016/06/08 Javascript
20分钟打造属于你的Bootstrap站点
2016/07/27 Javascript
关于在mongoose中填充外键的方法详解
2017/08/14 Javascript
Vue2.5 结合 Element UI 之 Table 和 Pagination 组件实现分页功能
2018/01/26 Javascript
在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件的流程
2018/03/21 Javascript
vue中的计算属性实例详解
2018/09/19 Javascript
Electron 如何调用本地模块的方法
2019/02/01 Javascript
利用js-cookie实现前端设置缓存数据定时失效
2019/06/18 Javascript
VUE组件中的 Drawer 抽屉实现代码
2019/08/06 Javascript
Jquery Datatables的使用详解
2020/01/30 jQuery
Node.JS如何实现JWT原理
2020/09/18 Javascript
[02:32]【DOTA2亚洲邀请赛】iceice,梦开始的地方
2017/03/13 DOTA
python持久性管理pickle模块详细介绍
2015/02/18 Python
python通过pil为png图片填充上背景颜色的方法
2015/03/17 Python
使用pdb模块调试Python程序实例
2015/06/02 Python
Python列表list操作符实例分析【标准类型操作符、切片、连接字符、列表解析、重复操作等】
2017/07/24 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
2020/01/14 Python
python 实现读取csv数据,分类求和 再写进 csv
2020/05/18 Python
澳大利亚墨水站Ink Station:墨水和碳粉打印机墨盒
2019/03/24 全球购物
希腊品牌鞋类销售网站:epapoutsia.gr
2020/03/18 全球购物
感谢信模板大全
2015/01/23 职场文书
教师岗位职责
2015/02/03 职场文书
银行求职信模板
2015/03/20 职场文书
工作态度怎么写
2015/06/25 职场文书
运动会通讯稿600字
2015/07/20 职场文书