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 http长连接客户端
Jun 12 Python
你眼中的Python大牛 应该都有这份书单
Oct 31 Python
python+opencv实现动态物体识别
Jan 09 Python
python操作oracle的完整教程分享
Jan 30 Python
Python设计模式之命令模式原理与用法实例分析
Jan 11 Python
Python产生一个数值范围内的不重复的随机数的实现方法
Aug 21 Python
django商品分类及商品数据建模实例详解
Jan 03 Python
Python 基于jwt实现认证机制流程解析
Jun 22 Python
在tensorflow实现直接读取网络的参数(weight and bias)的值
Jun 24 Python
Spy++的使用方法及下载教程
Jan 29 Python
python matplotlib工具栏源码探析三之添加、删除自定义工具项的案例详解
Feb 25 Python
Python时间操作之pytz模块使用详解
Jun 14 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专用数组排序类ArraySortUtil用法实例
2015/04/03 PHP
PHP中4种常用的抓取网络数据方法
2015/06/04 PHP
如何解决PHP无法实现多线程的问题
2015/09/25 PHP
php处理抢购类功能的高并发请求
2018/02/08 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
web前端开发也需要日志
2010/12/09 Javascript
JavaScript Title、alt提示(Tips)实现源码解读
2010/12/12 Javascript
在新窗口打开超链接的方法小结
2013/04/14 Javascript
jquery easyui滚动条部分设置介绍
2013/09/12 Javascript
Javascript编写俄罗斯方块思路及实例
2015/07/07 Javascript
jquery获得当前html页面源码的方法
2015/07/14 Javascript
jQuery文字横向滚动效果的实现代码
2016/05/31 Javascript
解析js如何获取css样式
2016/12/11 Javascript
获取当前月(季度/年)的最后一天(set相关操作及应用)
2016/12/27 Javascript
详解JS中的快速排序与冒泡
2017/01/10 Javascript
从零学习node.js之搭建http服务器(二)
2017/02/21 Javascript
layui分页效果实现代码
2017/05/19 Javascript
详解Angular.js中$http拦截器的介绍及使用
2017/07/04 Javascript
Bootstrap Table 删除和批量删除
2017/09/22 Javascript
解决JQuery全选/反选第二次失效的问题
2017/10/11 jQuery
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
2017/11/22 Javascript
Node.js log4js日志管理详解
2018/07/31 Javascript
JS+CSS实现随机点名(实例代码)
2019/11/04 Javascript
vue实现验证用户名是否可用
2021/01/20 Vue.js
python3访问sina首页中文的处理方法
2014/02/24 Python
在Python3中初学者应会的一些基本的提升效率的小技巧
2015/03/31 Python
11个并不被常用但对开发非常有帮助的Python库
2015/03/31 Python
python BeautifulSoup设置页面编码的方法
2015/04/03 Python
Python遍历目录并批量更换文件名和目录名的方法
2016/09/19 Python
Python生成并下载文件后端代码实例
2020/08/31 Python
澳大利亚旅游网站:Lastminute
2017/08/07 全球购物
澳洲的服装老品牌:SABA
2018/02/06 全球购物
写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔
2015/07/30 面试题
大学旷课检讨书
2014/01/28 职场文书
2015年安全月活动总结
2015/03/26 职场文书
MySQL中你可能忽略的COLLATION实例详解
2021/05/12 MySQL