python实现常用加密算法

需要用到的模块有系统自带的hashlib、base64、hmac,以及
第三方模块pyCrypto

1、MD5加密

import hashlib
def md5(data):
    m = hashlib.md5()
    m.update(data)
    return m.hexdigest()

2、SHA256加密

SHA256也称为HMAC_SHA256,hmac是Hash-based Message Authentication Code的简写,就是指哈希消息认证码,包含有很多种哈希加密算法,sha256是其中一种。

import hashlib,base64,hmac
def hmac_sha256_encrypt(message,secret):
    message = bytes(message).encode('utf-8')
    secret = bytes(secret).encode('utf-8')
    signature = base64.b64encode(hmac.new(secret, message, digestmod=hashlib.sha256).digest())
    return signature

3、RSA加解密

加密:

from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA
import base64,os

def rsa_encrypt(message):
    pem_path = os.path.join(os.path.dirname(os.path.dirname(__file__)),"exts","public.pem")
    with open(pem_path) as f:
        key = f.read()
        rsakey = RSA.importKey(key)
        cipher = Cipher_pkcs1_v1_5.new(rsakey)
        cipher_text = base64.b64encode(cipher.encrypt(message))
    return cipher_text

解密:

from Crypto import Random
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA
import base64,os

def rsa_decrypt(encrypt_text):
    pem_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "exts", "private.pem")
    # 伪随机数生成器
    random_generator = Random.new().read
    with open(pem_path) as f:
        key = f.read()
        rsakey = RSA.importKey(key)
        cipher = Cipher_pkcs1_v1_5.new(rsakey)
        text = cipher.decrypt(base64.b64decode(encrypt_text), random_generator)
    return text

3.1 RSA公钥加密,私钥解密

import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding


def RSA_Encrypt_by_publicKey(data,publicKeyPath):
    # 读取公钥数据
    key_file = open(publicKeyPath, 'rb')
    key_data = key_file.read()
    key_file.close()

    # 从公钥数据中加载公钥
    public_key = serialization.load_pem_public_key(
        key_data,
        backend=default_backend()
        )

    # 使用公钥对原始数据进行加密,使用PKCS#1 v1.5的填充方式
    out_data = public_key.encrypt(
        data.encode("utf-8"),
        padding.PKCS1v15()
    )

    ret = base64.b64encode(out_data).decode("utf-8")
    # 返回加密结果
    return ret


def RSA_Decrypt_by_privateKey(msg,privateKeyPath):
    # 读取原始数据
    data = base64.b64decode(msg.encode("utf-8"))

    # 读取私钥数据
    key_file = open(privateKeyPath, 'rb')
    key_data = key_file.read()
    key_file.close()

    # 从私钥数据中加载私钥
    private_key = serialization.load_pem_private_key(
        key_data,
        password=None,
        backend=default_backend()
    )

    # 使用私钥对数据进行解密,使用PKCS#1 v1.5的填充方式
    out_data = private_key.decrypt(
        data,
        padding.PKCS1v15()
    )

    # 返回解密结果
    return out_data.decode("utf-8")

4、SHA1withRSA加密

这种加密方式常用于一般接口中做签名校验,isPem为True的时候,传入的是密钥文件格式,以—-BEGIN PRIVATE KEY—-开头的多行文本;isPem为False时,传入的是私钥字符串privateKey。

import base64
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA

def sign(data,secret,isPem=False):
    if isPem:
        pem = secret
    else:
        pem = "-----BEGIN PRIVATE KEY-----\n"+"\n".join([secret[64*i:64*(i+1)] for i in range(len(secret)//64+1)])+"\n-----END PRIVATE KEY-----"
    private_key = RSA.importKey(pem)
    cipher = PKCS1_v1_5.new(private_key)
    h = SHA.new(data)
    signature = cipher.sign(h)
    return base64.b64encode(signature)

5、AES加解密

CBC模式:

from Crypto.Cipher import AES
import base64

def AES_CBC_encrypt(data, password, iv):
    BS = AES.block_size
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
    cipher = AES.new(password.encode("utf-8"), AES.MODE_CBC, iv.encode("utf-8"))
    data = cipher.encrypt(pad(data.encode("utf-8")))
    return base64.b64encode(data)

def AES_CBC_decrypt(data, password, iv):
    iv = iv.encode("utf-8")
    data = iv + base64.b64decode(data.decode("utf-8"))
    bs = AES.block_size
    if len(data) <= bs:
        return data
    unpad = lambda s: s[0:-ord(s[-1])]
    iv = data[:bs]
    cipher = AES.new(password.encode("utf-8"), AES.MODE_CBC, iv)
    data = unpad(cipher.decrypt(data[bs:]))
    return data

ECB模式:

from Crypto.Cipher import AES
import base64

def AES_ECB_encrypt(data, password="yyfax10086100861"):
    BS = AES.block_size
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
    cipher = AES.new(password.encode("utf-8"), AES.MODE_ECB)
    data = cipher.encrypt(pad(data.encode("utf-8")))
    return base64.b64encode(data)

def AES_ECB_decrypt(data, password="yyfax10086100861"):
    data = "0"*16 + base64.b64decode(data.decode("utf-8"))
    bs = AES.block_size
    if len(data) <= bs:
        return data
    unpad = lambda s: s[0:-ord(s[-1])]
    cipher = AES.new(password.encode("utf-8"), AES.MODE_ECB)
    data = unpad(cipher.decrypt(data[bs:]))
    return data

6、DES加解密

ECB模式:

from pyDes import *
import base64

def des_ecb_decrypt(source, key):
    source = base64.b64decode(source)
    source =  bytearray(source)
    source = [chr(x) for x in source]
    des_obj = des('        ', ECB, IV=None, pad=None, padmode=PAD_PKCS5)
    des_obj.setKey(key.encode('utf-8'))
    des_result = des_obj.decrypt(source)
    return des_result

def des_ecb_encode(source, key):
    des_obj = des('        ', ECB, IV=None, pad=None, padmode=PAD_PKCS5)
    des_obj.setKey(key.encode('utf-8'))
    source = [chr(ord(x)) for x in source]
    des_result = des_obj.encrypt(source)
    return base64.b64encode(des_result)