Python-Windows安装Crypto
Windows安装Crypto
m2crypto vs pycrypto vs pycryptodome
- m2crypto:30+的星星,windows的兼容性较差,pip上面默认的版本不是whl包(是源码包),导致基本上无法在windows上pip安装,只能借助于appveyor编译好的版本进行安装
- pycrypto:很久没有维护了,最后提交已经是2014年,不建议使用
- pycryptodome:克隆pycrypto的增强版本,1.3k+星星,linux和windows的兼容性较好。建议使用此版本
安装m2crypto
通过appveyor资源安装
pip 默认的包是源码包,windows不可以直接pip安装,只能通过其它办法安装
appveyor为开源项目Windowsg环境自动构建工具,开源项目包含appveyor.yml,则代表支持自动构建,可以直接在appveyor上下载相关编译好的资源
项目CI地址
https://ci.appveyor.com/project/m2crypto/m2crypto
选择和自己匹配的Environment
Environment: 主要是python的版本
Environment: PYTHON=C:\Python37-x64, PYTHON_VERSION=3.7.x, PYTHON_ARCH=64, OPENSSL_PATH=C:\OpenSSL-1-1-Win64, PYWIN32=pywin32-222.win-amd64-py3.7.exe, PYWIN32_RELEASE=b222, APPVEYOR_BUILD_WORKER_IMAGE=Visual Studio 2019
选择artifacts里面的资源
https://ci.appveyor.com/project/m2crypto/m2crypto/build/job/6l7jos7oylu9exmy/artifacts
编译好的资源
安装
# pip install https://ci.appveyor.com/api/buildjobs/6l7jos7oylu9exmy/artifacts/dist%2FM2Crypto-0.36.0-cp37-cp37m-win_amd64.whl
pip install M2Crypto-0.36.0-cp37-cp37m-win_amd64.whl
安装pycryptodome
https://ci.appveyor.com/project/Legrandin/pycryptodome
安装
pip 默认的包是whl,windows可以直接pip安装
pip install pycryptodome
加密实现
参考文档:https://gist.github.com/Frizz925/ac0fb026314807959db5685ac149ed67
下面的加密主要实现了:
- 将原密码进行md5计算:实现了密码的兼用性
- iv的随机性
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020-09-01 14:26
# @Author : zaza
# @Email : 260458726@qq.com
# @File : crypto.py
import random
import string
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
from Crypto.Util import Padding
from hashlib import md5
class SymmetricEncryption(object):
"""
>>> # 加、解密测试
>>> s = SymmetricEncryption(key='zaza')
>>> # 加密
>>> data = s.encrypt('zaza')
>>> # 解密
>>> s.decrypt(data)
'zaza'
>>> # 自定义向量加、解密测试
>>> s = SymmetricEncryption(key='yaya')
>>> data = s.encrypt('yaya', '47a79039cc54d688')
>>> print(data)
w9Nd2IHjHgCU8QaD4txfYw==.NDdhNzkwMzljYzU0ZDY4OA==
>>> s.decrypt(data)
'yaya'
>>> # key长度正常测试
>>> s = SymmetricEncryption(key='YWySvcV)k6Y!lcgd2njF*OqJW^uiz&qG', md5_key=False)
>>> data = s.encrypt('zaza', '47a79039cc54d688')
>>> print(data)
Ec7rjeW7uP0J5ps9U+MLTg==.NDdhNzkwMzljYzU0ZDY4OA==
>>> s.decrypt(data)
'zaza'
>>> # key长度异常测试
>>> s = SymmetricEncryption(key='yaya', md5_key=False)
>>> s.encrypt('zaza')
Traceback (most recent call last):
...
ValueError: Incorrect AES key length (4 bytes)
"""
def __init__(self, key, md5_key=True):
"""
对称加密,使用aes_256_cbc进行加解密
:param key: 支持string和bytes类型
:param md5_key: 将key进行md5计算,成为最终的加密key,经过md5计算保证了key长度为32位
"""
__key = key if type(key) is bytes else key.encode('utf-8')
if md5_key:
self.key = md5(__key).hexdigest().encode('utf-8')
else:
self.key = __key
self.mode = AES.MODE_CBC
self.bs = AES.block_size
@staticmethod
def generate_key(length=32):
"""
密码生成器
:param length: 默认为32位长度
:return: 返回随机字符串
"""
chars = string.ascii_letters + string.digits + '!@#$%^&*()'
rnd = random.SystemRandom()
return ''.join(rnd.choice(chars) for i in range(length))
def encrypt(self, plaintext, iv=None):
"""
将明文转换为加密字符串:"{0}.{1}".format(body, iv)
解密数据为:由点进行数据分隔,body,iv数据为base64的字符串
:param plaintext: 需要加密的字符串
:param iv: 初始化向量,长度为16位
:return: "{0}.{1}".format(body, iv)
"""
plaintext = plaintext if type(plaintext) is bytes else plaintext.encode('utf-8')
if iv is None:
iv = self.generate_key(length=16).encode('utf-8')
else:
iv = iv if type(iv) is bytes else iv.encode('utf-8')
plaintext = Padding.pad(plaintext, self.bs)
cipher = AES.new(self.key, self.mode, iv)
# 将body,iv转换成base64的字符串类型
body = b64encode(cipher.encrypt(plaintext)).decode('utf-8')
iv = b64encode(iv).decode('utf-8')
result = "{0}.{1}".format(body, iv)
return result
def decrypt(self, ciphertext):
"""
数据格式:"{0}.{1}".format(body, iv) 数据为base64的字符串
解密数据为:由点进行数据分隔,body,iv数据为base64的字符串
:param ciphertext:
:return:
"""
body, iv = ciphertext.split(".")
body = b64decode(body.encode('utf-8'))
iv = b64decode(iv.encode('utf-8'))
cipher = AES.new(self.key, self.mode, iv)
body = Padding.unpad(cipher.decrypt(body), self.bs).decode('utf-8')
return body
if __name__ == '__main__':
import doctest
doctest.testmod(verbose=True)
参考
- 原文作者:zaza
- 原文链接:https://zazayaya.github.io/2020/12/02/python-windows-crypto.html
- 说明:转载本站文章请标明出处,部分资源来源于网络,如有侵权请及时与我联系!