栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python加解密库——pycrypto(pycryptodome)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python加解密库——pycrypto(pycryptodome)

文章目录
  • 简介
  • 安装
    • 方法一:Visual Studio
    • 方法二:pycryptodome(推荐)
  • 初试
  • 公钥
  • 加解密
    • 对称加密
    • 非对称加密
  • 数字签名
  • 哈希函数
  • 安全通信
  • 加密IO
  • 封装
  • 遇到的坑
  • 参考文献

简介

pycrypto 实现了哈希函数(如 SHA256)和加密算法(如 AES、DES、RSA)。

注意!pycrypto 已很久未维护,有安全漏洞。

建议使用 pycryptodome 替代 pycrypto,它是后者的一个分支,一直在维护。




安装

以下方法均可,推荐方法二。



方法一:Visual Studio

Windows 需要安装 Visual Studio 2015 或以上版本,本人是 Visual Studio 2017,安装方法大同小异。

cd C:Program Files (x86)Microsoft Visual Studio2017ProfessionalVCAuxiliaryBuild
vcvars64.bat
set CL=-FI"C:Program Files (x86)Microsoft Visual Studio2017ProfessionalVCToolsMSVC14.16.27023includestdint.h"
pip install pycrypto



方法二:pycryptodome(推荐)

也可以用 pycryptodome 替代 pycrypto,它是后者的一个分支,一直在维护。

pip uninstall pycrypto
pip install pycryptodome




初试

SHA256 计算散列值(哈希值)

from Crypto.Hash import SHA256

hash = SHA256.new()
hash.update('message'.encode())
print(hash.digest())
# b'xabSnx13xe4Yx14x98+yxf9xb7xe3xfbxa9x94xcfxd1xf3xfb"xf7x1cxeax1axfbxf0+Fx0cmx1d'




公钥

公钥系统下,发送方和接收方使用不同密钥——公钥或私钥。

场景发送方接收方
加解密公钥私钥
数字签名私钥公钥
from Crypto.PublicKey import RSA

key_pair = RSA.generate(4096)  # 生成密钥对
open('public.pem', 'wb').write(key_pair.public_key().export_key('PEM'))  # 导出公钥
open('private.pem', 'wb').write(key_pair.export_key('PEM'))  # 导出私钥




加解密

三种加密方式:

  1. 对称加密:参与方使用相同密钥进行加解密,速度快,适合处理大量数据。如 AES。
  2. 非对称加密:发送方使用公钥加密,接收方使用私钥解密,速度慢。如 RSA。
  3. 混合加密:将上述加密进行组合,优点兼具,非对称加密用于保护有效时间短的对称密钥,对称加密用于加密实际数据。



对称加密

两种对称加密方式:

  1. 流加密:一次加密一个字节数据。如 ChaCha20、XChaCha20 和 Salsa20
  2. 分组密码:对固定数量的数据进行加密。如 AES,一次加密 16 个字节。

Salsa20 加密

from Crypto.Cipher import Salsa20

# 加密方
plaintext = b'Hello World!'  # 明文
key = b'0123456789012345'  # 密钥
cipher = Salsa20.new(key=key)
msg = cipher.nonce + cipher.encrypt(plaintext)  # 消息=随机数+密文

# 解密方
key = b'0123456789012345'  # 密钥
msg_nonce = msg[:8]
ciphertext = msg[8:]
cipher = Salsa20.new(key=key, nonce=msg_nonce)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)
# b'Hello World!'

AES 加密

from Crypto.Cipher import AES

# 加密方
plaintext = b'Hello World!'  # 明文
key = b'0123456789012345'  # 密钥
cipher = AES.new(key, AES.MODE_EAX)
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(plaintext)

# 解密方
key = b'0123456789012345'  # 密钥
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)
try:
    cipher.verify(tag)  # 验证真实性
    print(plaintext)
except ValueError:
    print('密钥不正确或消息被破坏')



非对称加密

RSA 加密

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

# 生成公私密钥
key_pair = RSA.generate(1024)
open('public.pem', 'wb').write(key_pair.public_key().export_key('PEM'))
open('private.pem', 'wb').write(key_pair.export_key('PEM'))

# 加密方
plaintext = b'Hello World!'
public_key = RSA.importKey(open('public.pem').read())
cipher = PKCS1_OAEP.new(public_key)
ciphertext = cipher.encrypt(plaintext)

# 解密方
private_key = RSA.importKey(open('private.pem').read())
cipher = PKCS1_OAEP.new(private_key)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)

实际场景下,密钥长度应使用 3072 或 4096 位




数字签名

用于保证完整性和不可抵赖性。

PKCS#1 RSA 签名

from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15

# 生成公私密钥
key_pair = RSA.generate(1024)
open('public.pem', 'wb').write(key_pair.public_key().export_key('PEM'))
open('private.pem', 'wb').write(key_pair.export_key('PEM'))

# 发送方
plaintext = b'Hello World!'
private_key = RSA.importKey(open('private.pem').read())
signer = pkcs1_15.new(private_key)
hash = SHA256.new(plaintext)
signature = signer.sign(hash)

# 接收方
plaintexts = [b'Hello World!', b'abc']
public_key = RSA.importKey(open('public.pem').read())
signer = pkcs1_15.new(public_key)
for plaintext in plaintexts:
    hash = SHA256.new(plaintext)
    try:
        signer.verify(hash, signature)
        print('合法')
    except:
        print('非法')

推荐阅读:什么是数字签名?




哈希函数

用于信息摘要。

将任意二进制字符串作为输入,并产生类似随机的固定长度的输出,即摘要或哈希值。

SHA256 计算散列值(哈希值)

from Crypto.Hash import SHA256

hash = SHA256.new()
hash.update('message'.encode())
print(hash.digest())
# b'xabSnx13xe4Yx14x98+yxf9xb7xe3xfbxa9x94xcfxd1xf3xfb"xf7x1cxeax1axfbxf0+Fx0cmx1d'




安全通信

PBKDF2 进行口令保护

from Crypto.Hash import SHA512
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes

password = '123456'  # 口令
salt = get_random_bytes(16)  # 加盐
keys = PBKDF2(password, salt, 64, count=1000000, hmac_hash_module=SHA512)
key1 = keys[:32]
key2 = keys[32:]

推荐阅读:PBKDF2函数,比「Hash加盐」更好的口令保护方案




加密IO




封装




遇到的坑




参考文献
  1. pycrypto GitHub
  2. PyCryptodome GitHub
  3. PyCryptodome Documentation
  4. python 3.6.5 在windows下安装PyCrypto
  5. windows下python3.9安装pycrypto成功总结
  6. Installing pycrypto on windows (popular solution not working)
  7. How do I install PyCrypto on Windows?
  8. RSA Encrypt / Decrypt
  9. 什么是数字签名?
  10. PBKDF2函数,比「Hash加盐」更好的口令保护方案
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/954691.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号