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实现的二叉树算法和kmp算法实例
Apr 25 Python
进一步理解Python中的函数编程
Apr 13 Python
Python的__builtin__模块中的一些要点知识
May 02 Python
Python实现将DOC文档转换为PDF的方法
Jul 25 Python
python+VTK环境搭建及第一个简单程序代码
Dec 13 Python
windows 下python+numpy安装实用教程
Dec 23 Python
python批量赋值操作实例
Oct 22 Python
详解pandas数据合并与重塑(pd.concat篇)
Jul 09 Python
python中for循环把字符串或者字典添加到列表的方法
Jul 20 Python
Django Form 实时从数据库中获取数据的操作方法
Jul 25 Python
python数字类型math库原理解析
Mar 02 Python
在vscode中启动conda虚拟环境的思路详解
Dec 25 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自动生成月历代码
2006/10/09 PHP
使用sockets:从新闻组中获取文章(一)
2006/10/09 PHP
站长助手-网站web在线管理程序 v1.0 下载
2007/05/12 PHP
php中防止SQL注入的最佳解决方法
2013/04/25 PHP
windwos下使用php连接oracle数据库的过程分享
2014/05/26 PHP
浅谈php和js中json的编码和解码
2016/10/24 PHP
phpStudy配置多站点多域名和多端口的方法
2017/09/01 PHP
laravel获取不到session的三种解决办法【推荐】
2018/09/16 PHP
PHP实现微信提现(企业付款到零钱)
2019/08/01 PHP
popdiv
2006/07/14 Javascript
Javascript毫秒数用法实例
2015/02/05 Javascript
移动Web中图片自适应的两种JavaScript解决方法
2015/06/18 Javascript
浅析Node.js中的内存泄漏问题
2015/06/23 Javascript
javascript bom是什么及bom和dom的区别
2015/11/26 Javascript
使用angularjs创建简单表格
2016/01/21 Javascript
关于JavaScript数组你所不知道的3件事
2016/08/24 Javascript
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
2016/12/14 Javascript
微信小程序 封装http请求实例详解
2017/01/16 Javascript
原生JS获取元素的位置与尺寸实现方法
2017/10/18 Javascript
vue 文件目录结构详解
2017/11/24 Javascript
react 移动端实现列表左滑删除的示例代码
2019/07/04 Javascript
我所理解的JavaScript中的this指向
2020/09/04 Javascript
Python 读取某个目录下所有的文件实例
2018/06/23 Python
python+selenium实现QQ邮箱自动发送功能
2019/01/23 Python
python中栈的原理及实现方法示例
2019/11/27 Python
Windows下python3安装tkinter的问题及解决方法
2020/01/06 Python
Python类如何定义私有变量
2020/02/03 Python
Python3基本输入与输出操作实例分析
2020/02/14 Python
基于注解实现 SpringBoot 接口防刷的方法
2021/03/02 Python
JVM是一个编译程序还是解释程序
2012/09/11 面试题
励志演讲稿600字
2014/08/21 职场文书
二婚主持词
2015/06/30 职场文书
小学生优秀作文范文(六篇)
2019/07/10 职场文书
人生感悟经典句子
2019/08/20 职场文书
导游词之无锡唐城
2019/12/12 职场文书
MySQL中CURRENT_TIMESTAMP的使用方式
2021/11/27 MySQL