加解密
https://docs.python.org/3/library/crypto.html
三方库推荐,https://cryptography.io/en/latest/
Criptography,https://pypi.org/project/cryptography/
PyCryptodome,a fork of PyCrypto,https://pypi.org/project/pycryptodome/
PyCrypto,unmaintained,https://www.pycrypto.org/
PyNaCl,https://pypi.org/project/PyNaCl/
通用哈希算法
hash,哈希、散列,散列函数是密码学中的基础工具,并非加密算法。
https://docs.python.org/3/library/hashlib.html
MD5
Message Digest 5,信息摘要5,用于生成文件唯一摘要,可近似认为不同文件有唯一MD5值(信息摘要)。
MD5已被攻破(即找到了在一定复杂度内找到碰撞的算法),王小云院士有相关研究,RFC6151中禁止MD5用于HMAC。
- 固定压缩,从任意长度信息计算出固定128位的哈希值
- 容易计算,基于原信息计算出MD5值较为容易
- 抗碰撞,伪造一段相同MD5值的信息很难(但并非不可)
- 抗修改,改动信息(即使一个字节)会造成MD5值发生较大变化
文件完整性校验
软件下载通常会提供MD5等方式校验文件,https://dev.mysql.com/downloads/mysql/
云盘秒传
上传文件时计算文件MD5,云盘系统中有该MD5值的文件即可秒传。
# 可以用来检测有没有抄错诗(笑)
import hashlib
print(hashlib.md5("黄河远上白云间一片孤城万仞山羌笛何须怨杨柳春风不度玉门关".encode(
"UTF-8")).hexdigest()) # 3a3b5f524e4b6b056b373f1ed28c2ab6
print(hashlib.md5("黄河远上白云一片孤城万仞山羌笛何须怨杨柳春风不度玉门关".encode(
"UTF-8")).hexdigest()) # e66786b96a78b740f9de999e3384317b
# 盐值,就是把一个值和原文混合一起计算
# 静态盐
md5 = hashlib.md5(bytes('盐值加密', encoding='utf8'))
md5.update(b"Hello World!")
print(md5.hexdigest())
# 动态盐,比如用户名密码,使用用户名一部分加某些字符作为盐,可以基本做到每个用户的盐不一样
md5 = hashlib.md5(bytes('盐值', encoding='utf8'))
md5.update(b"Hello ") # 可以分次
md5.update(b"World!")
print(md5.hexdigest())
SHA
Secure Hash Algorithm,安全哈希算法,一系列算法,包括SHA-0、SHA-1、SHA-2(SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256)和SHA3(SHA3-224、SHA3-256、SHA3-384、SHA3-512、SHAKE128、SHAKE256)。
SHA-0、SHA-1已被攻破,王小云院士有相关研究。
import hashlib
print(hashlib.sha256("黄河远上白云间一片孤城万仞山羌笛何须怨杨柳春风不度玉门关".encode(
"UTF-8")).hexdigest()) # c3df60edca13163d4892f336227669790bd8faed37359dee37fafc83876b0102
print(hashlib.sha256("黄河远上白云一片孤城万仞山羌笛何须怨杨柳春风不度玉门关".encode(
"UTF-8")).hexdigest()) # 5c4c88e93a5931a19dcc53d13a1930d7a42390bf1d231d65e7858bac8f4b134f
MAC
https://docs.python.org/3/library/hmac.html
Message Authentication Code,信息认证码,基于密钥、原始消息、MAC算法三者计算出消息的MAC,密钥共享与发送者和接收者之间,可近似保证消息完整性和发送接收双方身份合法性。
HMAC
keyed-hash message authentication code,密钥散列消息认证码,MAC实现之一,MAC算法采用哈希函数,例如SHA家族,即基于密钥、原始消息、哈希函数计算MAC。
import hmac
import hashlib
print(hmac.new(
b'a secret key', # 密钥,消息发送双方共享
'Hello World'.encode("UTF-8"), # 原始消息
hashlib.sha256).hexdigest()) # 摘要算法
对称加密算法
对称加密算法加密和解密使用相同密钥。
EDS
Data Enctyption Standard,DES,数据加密标准,有时称EDS使用的算法为EDA(Data Encryption Algorithm)。后被3DES取代。
TDEA(3DES)
Triple Data Encryption Algorithm,TDEA,三重数据加密算法,亦称3DES,对每个数据块使用三次DES。后被AES取代。
AES
Advanced Encryption Standard, AES,高级加密标准。
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = os.urandom(32) # 256 bits
iv = os.urandom(16)
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
encryptor = cipher.encryptor()
ct = encryptor.update(b"a secret message") + encryptor.finalize()
print(ct)
decryptor = cipher.decryptor()
print(decryptor.update(ct) + decryptor.finalize())
非对称加密算法
非对称加密算法加密和解密使用不同密钥,分为私钥和公钥,私钥私人持有,公钥公开分发,私钥加密公钥解密和公钥加密私钥解密均有不同应用场景。
RSA
RSA由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)共同提出,RAS取自三者姓氏首字母。
# c
import base64
import rsa
from rsa import common
# 使用 rsa库进行RSA签名和加解密
class RsaUtil(object):
PUBLIC_KEY_PATH = 'xxxxpublic_key.pem' # 公钥
PRIVATE_KEY_PATH = 'xxxxxprivate_key.pem' # 私钥
# 初始化key
def __init__(self,
company_pub_file=PUBLIC_KEY_PATH,
company_pri_file=PRIVATE_KEY_PATH):
if company_pub_file:
self.company_public_key = rsa.PublicKey.load_pkcs1_openssl_pem(open(company_pub_file).read())
if company_pri_file:
self.company_private_key = rsa.PrivateKey.load_pkcs1(open(company_pri_file).read())
def get_max_length(self, rsa_key, encrypt=True):
"""加密内容过长时 需要分段加密 换算每一段的长度.
:param rsa_key: 钥匙.
:param encrypt: 是否是加密.
"""
blocksize = common.byte_size(rsa_key.n)
reserve_size = 11 # 预留位为11
if not encrypt: # 解密时不需要考虑预留位
reserve_size = 0
maxlength = blocksize - reserve_size
return maxlength
# 加密 支付方公钥
def encrypt_by_public_key(self, message):
"""使用公钥加密.
:param message: 需要加密的内容.
加密之后需要对接过进行base64转码
"""
encrypt_result = b''
max_length = self.get_max_length(self.company_public_key)
while message:
input = message[:max_length]
message = message[max_length:]
out = rsa.encrypt(input, self.company_public_key)
encrypt_result += out
encrypt_result = base64.b64encode(encrypt_result)
return encrypt_result
def decrypt_by_private_key(self, message):
"""使用私钥解密.
:param message: 需要加密的内容.
解密之后的内容直接是字符串,不需要在进行转义
"""
decrypt_result = b""
max_length = self.get_max_length(self.company_private_key, False)
decrypt_message = base64.b64decode(message)
while decrypt_message:
input = decrypt_message[:max_length]
decrypt_message = decrypt_message[max_length:]
out = rsa.decrypt(input, self.company_private_key)
decrypt_result += out
return decrypt_result
# 签名 商户私钥 base64转码
def sign_by_private_key(self, data):
"""私钥签名.
:param data: 需要签名的内容.
使用SHA-1 方法进行签名(也可以使用MD5)
签名之后,需要转义后输出
"""
signature = rsa.sign(str(data), priv_key=self.company_private_key, hash='SHA-1')
return base64.b64encode(signature)
def verify_by_public_key(self, message, signature):
"""公钥验签.
:param message: 验签的内容.
:param signature: 对验签内容签名的值(签名之后,会进行b64encode转码,所以验签前也需转码).
"""
signature = base64.b64decode(signature)
return rsa.verify(message, signature, self.company_public_key)
ECC
Elliptic Curve Cryptography,ECC,椭圆曲线密码学,基于椭圆曲线的非对称加密算法。
DSA
…
信息摘要,message digest
消息摘要算法是哈希算法的一种应用场景,相比于一般哈希算法,消息摘要算法要保证逆向难度大、抗碰撞,消息摘要用于对消息计算出“数字指纹”。
- 摘要保证消息完整性
数字签名,digital signature
数字签名用于保证消息完整性、发送者身份认证,并不用于加密信息。
RSA算法可用于数字签名。RSA签名,对消息明文使用摘要算法计算摘要值,使用RAS算法和私钥对摘要信息加密得到签名。RSA验签,对消息明文使用摘要算法计算摘要值,使用RSA算法和公钥对签名进行解密获取摘要值,对比两个摘要值,不一致说明消息被篡改,一致可以说明消息正确且发送人所持私钥和收信人所持公钥对应。
私钥签名,公钥验签。
- 摘要保证消息完整性
- 解密出摘要发信人可以确认发信人一定持有配对私钥,基于公钥可确认发信人身份
数字证书,digital certificate
PKI,Public Key Infrastructure,公开密钥基础设施,包含证明书、认证机构、证书库三要素,用于签发数字证书,数字证书遵循X.509。
数字证书解决数字签名中公钥信任问题,数字签名保证信息一定由收信人所持公钥的对应私钥持有人发送,若公钥本身有问题,如A将B的公钥换成自己的就可以使用自己的私钥冒充B发送信息,数字证书是由可信任三方证书认证机构私钥对信息发送方公钥和发送方身份信息进行加密,发送消息是连同数字证书一同发送,可以保证公钥持有人的身份。
数字证书相当于将公钥持有人身份篡改风险转移到CA(Certificate Authority)机构,依赖于CA机构的受信任程度,若CA机构被攻破并篡改信息,证书依然不可信。
SSL证书是数字证书的一种。
数字信封,digital envelope
封信封,使用对称算法和密钥对明文加密得到密文,使用非对称算法和公钥对对称密钥加密获取密钥密文。此时信息已加密,加密密钥已加密,使用的是公钥,只有持有私钥的人可以获取信件信息。
解信封,使用非对称算法和私钥对密钥密文解密获取对称密钥,使用对称密钥解密信件信息。
公钥加密,私钥解密。
相关文件
Privacy Enhanced Mail,PEM
文本文件,以”.pem”、”.cer”、”.crt”、”.key”为后缀名,由二进制文件经BASE64编码所得,通常包括以 “—–BEGIN …” 开头和 “—–END …” 结尾的边界行,可以是CERTIFICATE 、CERTIFICATE REQUEST、 PRIVATE KEY 、X509 CRL,用于标识起始和结束部分
PEM 文件可以包含多个不同类型的数据,例如证书、私钥、证书链等。
通常用于存储和传输X.509数字证书和相关的密钥
Personal Information Exchange,PFX
二进制文件,以.pfx、.p12为后缀名
PFX 文件通常包含证书、私钥和可选的密码,用于保护这些敏感信息。
格式通常用于将证书和私钥打包到一个文件中,以便于导入到应用程序或操作系统的密钥库中,例如在Web服务器上配置SSL证书时常用