base64加密
import base64
def to_base64(str_to_base64):
return base64.b64.encode(str_to_base64.eccode('utf-8'))
base64解密
import base64
def get_base64(str_to_base64):
return base64.b64decode(str_to_base64)
MD5加密(不可逆)
import hashlib
"""
MD5 Message-Digest Algorithm,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),
用于确保信息传输完整一致。MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。
update() 方法内传参为二进制数据 所以需要将字符串数据 encode()
作用:加密用户密码;保证数据唯一性(MD5可以保证唯一性);比较文件是否被篡改等
"""
def get_md5(str):
hash_md5 = hashlib.md5()
hash_md5.update(str.encode("utf-8"))
return hash_md5.hexdigest()
SHA1加密(不可逆)
"""
SHA1的全称是Secure Hash Algorithm(安全哈希算法) 。SHA1基于MD5,加密后的数据长度更长,
它对长度小于264的输入,产生长度为160bit的散列值。比MD5多32位,因此,比MD5更加安全,但SHA1的运算速度就比MD5要慢
"""
def get_sha1(str):
hash_sha1 = hashlib.sha1()
hash_sha1.update(str.encode("utf-8"))
return hash_sha1.hexdigest()
RSA加解密
import rsa
import os
"""
rsa 加解密
加密:公钥加密,私钥解密;
签名:私钥签名,公钥验签。
"""
class MyRSA:
def __init__(self):
self.public_key, self.private_key = rsa.newkeys(nbits=512)
def save_rsa(self, public_key_filename, private_key_filename, save_path):
"""
保存秘钥文件
"""
with open(os.path.join(save_path, public_key_filename), "wb") as f:
f.write(self.public_key.save_pkcs1())
with open(os.path.join(save_path, private_key_filename), "wb") as f:
f.write(self.private_key.save_pkcs1())
def read_rsa_public(self, public_key_filename):
"""
读取rsa公钥
:param public_key_filename: rsa 公钥文件地址
:return: 公钥
"""
with open(public_key_filename, 'rb') as publickfile:
pub = publickfile.read()
pubkey = rsa.PublicKey.load_pkcs1(pub)
return pubkey
def read_rsa_private(self, private_key_filename):
"""
读取rsa私钥
:param private_key_filename: rsa 私钥文件地址
:return: 私钥
"""
with open(private_key_filename, 'rb') as privatefile:
priv = privatefile.read()
privkey = rsa.PrivateKey.load_pkcs1(priv)
return privkey
def encrypt(self, str, public_key=None):
"""
使用公钥加密。如果传入了公钥,则使用传入的公钥加密;如果没有传入公钥,则使用初始化创建实例时的公钥加密。
:param str: 待加密的字符串
:param public_key: 公钥
:return: 加密后的数据,bytes
"""
if public_key:
rsa.encrypt(message=str.encode("utf-8"), pub_key=public_key)
return rsa.encrypt(message=str.encode("utf-8"), pub_key=self.public_key)
def decrypt(self, str, private_key=None):
"""
使用私钥解密. 如果传入了私钥,则使用传入的私钥解密;如果没有传入私钥,则使用初始化创建实例时的私钥解密。
:param str: 待解密的数据
:param private_key: 私钥
:return: 解密后的数据,str
"""
if private_key:
return rsa.decrypt(str, priv_key=private_key).decode("utf-8")
return rsa.decrypt(str, priv_key=self.private_key).decode("utf-8")
def sign(self, message, private_key, hash_method="SHA-256"):
"""
使用私钥进行签名. 默认hash算法为:'sha256',也可以使用 md5 或其他hash算法
:param message: 要签名的数据
:param private_key: 私钥
:param hash_method: hash算法
:return: 签名后的数据
"""
sign_result = rsa.sign(message=message, priv_key=private_key, hash_method=hash_method)
return sign_result
def verify(self, message, sign, public_key):
"""
验签,使用公钥验证签名是否正确。如果正确,则返回签名算法,否则返回验证失败
:param message: 已加密的数据
:param sign: 已签名的数据
:param public_key: 公钥
:return: 验签正确:返回签名算法;验签错误:返回验证失败 False
"""
try:
verify = rsa.verify(message=message, signature=sign, pub_key=public_key)
return verify
except rsa.VerificationError:
return False
if __name__ == "__main__":
r = MyRSA()
r.save_rsa("rsa_pub.pem", "rsa_priv.pem", "./")
result = r.encrypt("nishiwode")
print(result)
sign_str = r.sign(result, r.private_key)
print(sign_str)
sign_end = r.verify(result, sign_str, r.read_rsa_private(private_key_filename="./rsa_priv.pem"))
print(sign_end)
if sign_end:
end = r.decrypt(result)
print(end)
AES加解密
from Crypto import Random
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
"""
pip install pycryptodome
AES加密方式有五种:ECB, CBC, CTR, CFB, OFB
CBC加密需要一个十六位的key(密钥)和一个十六位iv(偏移量) 常用
ECB加密不需要iv
cryptor不能写在主函数中同时给加密函数与解密函数使用,所以加密和解密都要重新创建对象
"""
class MyAES:
def __init__(self, key, mode=AES.MODE_CBC, iv=Random.new().read(AES.block_size)):
"""
key 秘钥必须是16(AES-128),24, 32
iv 长度等于AES块大小的不可重复的秘钥向量
本类内实现了 ECB, CBC 两种加密模式,默认为 AES.MODE_CBC 加密模式
"""
self.key, self.mode, self.iv = key.encode(), mode, iv
def __add_to_16(self, text):
""" 如果string不足16位则用空格补齐16位 """
if len(text.encode()) % 16:
add = 16 - (len(text.encode()) % 16)
else:
add = 0
text += ("\0" * add)
return text.encode()
def encode_aes(self, text):
""" 使用 AES 加密字符串 """
if self.mode == AES.MODE_ECB:
cryptos = AES.new(key=self.key, mode=self.mode)
elif self.mode == AES.MODE_CBC:
cryptos = AES.new(key=self.key, mode=self.mode, iv=self.iv)
cipher_text = cryptos.encrypt(self.__add_to_16(text))
return b2a_hex(cipher_text)
def decode_aes(self, text):
""" aes 解密 并去掉补足的空格"""
if self.mode == AES.MODE_ECB:
cryptos = AES.new(key=self.key, mode=self.mode)
elif self.mode == AES.MODE_CBC:
cryptos = AES.new(key=self.key, mode=self.mode, iv=self.iv)
plain_text = cryptos.decrypt(a2b_hex(text))
return bytes.decode(plain_text).rstrip("\0")
if __name__ == '__main__':
a = MyAES(key="this is a 16 key", mode=AES.MODE_CBC)
result = a.encode_aes("nishiwode")
print(result)
r = a.decode_aes(result)
print(r)