python加密解密库cryptography使用openSSL生成的密匙加密解密


Posted in Python onFebruary 11, 2020

密匙使用步骤一般是:

    1. 私匙签名,发送签名后的数据, 公匙验证。

    2.公匙加密,发送加密后的数据,私匙解密。

一般使用情景是通过 openssl 生成密匙后再操作的。Linux下生成密匙也很简单。

yum 安装 openssl

yum -y install openssl

生成三个密匙文件。

rsa_private_key.pem 私匙文件

rsa_private_key_pkcs8.pem  pkcs8格式私匙, 

rsa_public_key.pem 公匙

openssl genrsa -out rsa_private_key.pem  1024 

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem 

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

导入私匙:

序列化密钥可以选择使用密码在磁盘上进行加密。在这个例子中,我们加载了一个未加密的密钥,因此我们没有提供密码。如果密钥被加密,我们可以传递一个bytes对象作为 password参数。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
 
# 已有sar私匙, 导入
with open('Key.pem', 'rb') as key_file:
  private_key = serialization.load_pem_private_key(
    key_file.read(),
    password=None,
    backend=default_backend()
  )

签名:

私钥可用于签署消息。这允许任何拥有公钥的人验证该消息是由拥有相应私钥的人创建的。RSA签名需要特定的散列函数,并使用填充。以下是message使用RSA 进行签名的示例,带有安全散列函数和填充:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
 
# 已有sar私匙, 导入
with open('Key.pem', 'rb') as key_file:
  private_key = serialization.load_pem_private_key(
    key_file.read(),
    password=None,
    backend=default_backend()
  )
 
message = b"aaaa, bbbb, cccc"
 
# 签名操作
signature = private_key.sign(
  message,
  padding.PSS(
    mgf=padding.MGF1(hashes.SHA256()),
    salt_length=padding.PSS.MAX_LENGTH
  ),
  hashes.SHA256()
)
print('签名后数据: ', signature)

有效的签名填充是 PSS和 PKCS1v15.PSS 是任何新协议或应用的推荐选择,PKCS1v15 只应用于支持传统协议。

如果您的数据太大而无法在单个调用中传递,则可以分别对其进行散列并使用该值 Prehashed。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import utils
 
# 已有sar私匙, 导入
with open('Key.pem', 'rb') as key_file:
  private_key = serialization.load_pem_private_key(
    key_file.read(),
    password=None,
    backend=default_backend()
  )
 
# 如果您的数据太大而无法在单个调用中传递,则可以分别对其进行散列并使用该值 Prehashed。
 
 
chosen_hash = hashes.SHA256()
hasher = hashes.Hash(chosen_hash, default_backend())
hasher.update(b"data &")
hasher.update(b"more data")
digest = hasher.finalize()
sig = private_key.sign(
  digest,
  padding.PSS(
    mgf=padding.MGF1(hashes.SHA256()),
    salt_length=padding.PSS.MAX_LENGTH
  ),
  utils.Prehashed(chosen_hash)
)
print('签名后数据: ', sig)

验证:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
 
# 已有sar私匙, 导入
with open('Key.pem', 'rb') as key_file:
  private_key = serialization.load_pem_private_key(
    key_file.read(),
    password=None,
    backend=default_backend()
  )
 
message = b"123 xiao"
 
# 签名
signature = private_key.sign(
  # 原始数据
  message,
  padding.PSS(
    mgf=padding.MGF1(hashes.SHA256()),
    salt_length=padding.PSS.MAX_LENGTH
  ),
  hashes.SHA256()
)
print('签名后的数据: ', signature)
 
 
# 公匙导入
with open('Key_pub.pem', 'rb') as key_file:
  public_key = serialization.load_pem_public_key(
    key_file.read(),
    backend=default_backend()
  )
  
  
# 签名数据与原始数据不对,抛出异常
# 如果验证不匹配,verify()会引发 InvalidSignature异常。
public_key.verify(
  # 签名数据
  signature,
  # 原始数据
  message,
  padding.PSS(
    mgf=padding.MGF1(hashes.SHA256()),
    salt_length=padding.PSS.MAX_LENGTH
  ),
  hashes.SHA256()
)

如果您的数据太大而无法在单个调用中传递,则可以分别对其进行散列并使用该值 Prehashed。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import utils
 
# 已有sar私匙, 导入
with open('Key.pem', 'rb') as key_file:
  private_key = serialization.load_pem_private_key(
    key_file.read(),
    password=None,
    backend=default_backend()
  )
 
chosen_hash = hashes.SHA256()
hasher = hashes.Hash(chosen_hash, default_backend())
hasher.update(b'data &')
hasher.update(b'more data')
digest = hasher.finalize()
sig = private_key.sign(
  digest,
  padding.PSS(
    mgf=padding.MGF1(hashes.SHA256()),
    salt_length=padding.PSS.MAX_LENGTH
  ),
  utils.Prehashed(chosen_hash)
)
print('签名后的数据: ', sig)
 
 
# 公匙导入
with open('Key_pub.pem', 'rb') as key_file:
  public_key = serialization.load_pem_public_key(
    key_file.read(),
    backend=default_backend()
  )
 
 
# 如果您的数据太大而无法在单个调用中传递,则可以分别对其进行散列并使用该值 Prehashed。
public_key.verify(
  sig,
  digest,
  padding.PSS(
    mgf=padding.MGF1(hashes.SHA256()),
    salt_length=padding.PSS.MAX_LENGTH
  ),
  utils.Prehashed(chosen_hash)
)

公匙,加密:

因为是使用进行加密的RSA加密有趣的是 公共密钥,这意味着任何人都可以对数据进行加密。数据然后使用私钥解密。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
 
 
# 公匙导入
with open('Key_pub.pem', 'rb') as key_file:
  public_key = serialization.load_pem_public_key(
    key_file.read(),
    backend=default_backend()
  )
 
 
message = b'test data'
ciphertext = public_key.encrypt(
  message,
  padding.OAEP(
    mgf=padding.MGF1(algorithm=hashes.SHA256()),
    algorithm=hashes.SHA256(),
    label=None
  )
)
print('加密数据: ', ciphertext)

私匙解密公私加密的信息:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
 
 
# 已有sar私匙, 导入
with open('Key.pem', 'rb') as key_file:
  private_key = serialization.load_pem_private_key(
    key_file.read(),
    password=None,
    backend=default_backend()
  )
  
 
plaintext = private_key.decrypt(
  # 加密的信息
  ciphertext,
  padding.OAEP(
    mgf=padding.MGF1(algorithm=hashes.SHA256()),
    algorithm=hashes.SHA256(),
    label=None
  )
)
 
print('解密数据: ', plaintext)

完整的公匙加密,私匙解密获取信息。

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
 
 
# 公匙导入
with open('Key_pub.pem', 'rb') as key_file:
  public_key = serialization.load_pem_public_key(
    key_file.read(),
    backend=default_backend()
  )
 
 
message = b'test data'
ciphertext = public_key.encrypt(
  message,
  padding.OAEP(
    mgf=padding.MGF1(algorithm=hashes.SHA256()),
    algorithm=hashes.SHA256(),
    label=None
  )
)
print('加密数据: ', ciphertext)
 
 
# 已有sar私匙, 导入
with open('Key.pem', 'rb') as key_file:
  private_key = serialization.load_pem_private_key(
    key_file.read(),
    password=None,
    backend=default_backend()
  )
  
 
plaintext = private_key.decrypt(
  # 加密的信息
  ciphertext,
  padding.OAEP(
    mgf=padding.MGF1(algorithm=hashes.SHA256()),
    algorithm=hashes.SHA256(),
    label=None
  )
)
 
print('解密数据: ', plaintext)

更多关于python加密解密库cryptography的使用方法请查看下面的相关链接

Python 相关文章推荐
python中常用的各种数据库操作模块和连接实例
May 29 Python
python 每天如何定时启动爬虫任务(实现方法分享)
May 21 Python
用python写扫雷游戏实例代码分享
May 27 Python
Python3使用pandas模块读写excel操作示例
Jul 03 Python
python format 格式化输出方法
Jul 16 Python
Anaconda2 5.2.0安装使用图文教程
Sep 19 Python
Python实现的逻辑回归算法示例【附测试csv文件下载】
Dec 28 Python
python opencv 简单阈值算法的实现
Aug 04 Python
python xlwt如何设置单元格的自定义背景颜色
Sep 03 Python
python矩阵运算,转置,逆运算,共轭矩阵实例
May 11 Python
python Scrapy爬虫框架的使用
Jan 21 Python
python 实现体质指数BMI计算
May 26 Python
如何通过python实现全排列
Feb 11 #Python
Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例
Feb 11 #Python
python 遗传算法求函数极值的实现代码
Feb 11 #Python
在django中使用apscheduler 执行计划任务的实现方法
Feb 11 #Python
django在保存图像的同时压缩图像示例代码详解
Feb 11 #Python
Python中包的用法及安装
Feb 11 #Python
使用Python实现牛顿法求极值
Feb 10 #Python
You might like
php xml文件操作实现代码(二)
2009/03/20 PHP
php中Smarty模板初体验
2011/08/08 PHP
ThinkPHP实现跨模块调用操作方法概述
2014/06/20 PHP
php使用curl并发减少后端访问时间的方法分析
2016/05/12 PHP
ThinkPHP5框架中使用JWT的方法示例
2020/06/03 PHP
IE php关于强制下载文件的代码
2008/08/23 Javascript
javascript实现了照片拖拽点击置顶的照片墙代码
2015/04/03 Javascript
基于Javascript实现二级联动菜单效果
2016/03/04 Javascript
JavaScript 2048 游戏实例代码(简单易懂)
2016/03/25 Javascript
js获取元素的标签名实现方法
2016/10/08 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
2017/02/20 Javascript
Node.js中的http请求客户端示例(request client)
2017/05/04 Javascript
详解使用angular-cli发布i18n多国语言Angular应用
2017/05/20 Javascript
深入理解react-router@4.0 使用和源码解析
2017/05/23 Javascript
ReactJs实现树形结构的数据显示的组件的示例
2017/08/18 Javascript
BootStrap下的弹出框加载select2框架失败的解决方法
2017/08/31 Javascript
Angular实现可删除并计算总金额的购物车功能示例
2017/12/26 Javascript
详解webpack打包nodejs项目(前端代码)
2018/09/19 NodeJs
原生JS实现轮播图效果
2018/10/12 Javascript
vue自定义指令之面板拖拽的实现
2019/04/14 Javascript
Vue $mount实战之实现消息弹窗组件
2019/04/22 Javascript
细说Vue组件的服务器端渲染的过程
2019/05/30 Javascript
vue+element-ui JYAdmin后台管理系统模板解析
2020/07/28 Javascript
通过实例解析jQ Ajax操作相关原理
2020/09/23 Javascript
在Mac OS上使用mod_wsgi连接Python与Apache服务器
2015/12/24 Python
python pandas实现excel转为html格式的方法
2018/10/23 Python
python/sympy求解矩阵方程的方法
2018/11/08 Python
python3 tkinter实现添加图片和文本
2019/11/26 Python
python shapely.geometry.polygon任意两个四边形的IOU计算实例
2020/04/12 Python
通俗易懂了解Python装饰器原理
2020/09/17 Python
StubHub墨西哥:购买和出售您的门票
2016/09/17 全球购物
办公室秘书自我鉴定
2014/01/18 职场文书
个人简历自我评价
2014/02/02 职场文书
贷款委托书范本
2014/04/08 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
数据库的高级查询六:表连接查询:外连接(左外连接,右外连接,UNION关键字,连接中ON与WHERE的不同)
2021/04/05 MySQL