常用的鉴权加密方式笔记

4 阅读3分钟
# 常见的加密
# 1,token加密,服务器返回
# 2,Sign签名加密 防篡改
# 把所有参数按照字母排序,拼上后端给的密钥secret,用MD5加密,生成一串字符串sign,每次请求必须带上sign和时间戳,才放行
# 3,HMAC-SHA256 签名  请求内容还是明文,后接了一个Sign防篡改
# 把所有参数按照字母升序排序;拼接成字符串(如 key1=value1key2=value2);使用 HMAC-SHA256 + 密钥 加密;转十六进制小写 / 大写;带上时间戳防止重放
# 4,AES对称加密 一把钥匙,不想让工具看到请求内容
# 加密解密用同一套密钥(所以叫 “对称”);通常需要:key + iv(key为密钥,iv为偏移量,加盐随机量,会传给后端);一般输出Base64字符串; AES-128 16位密钥
# 5,RSA非对称加密 两把钥匙 公钥和私钥
# 6,JWT鉴权 Json Web Token 本质就是一种规范格式的 Token,现在前后端分离、微服务、小程序、APP 几乎全用它
# Header:加密算法(告诉后端用什么算法加密);Payload:存放用户信息(user_id、手机号、过期时间等);Signature:签名,防止篡改
# JWT鉴权 Json Web Token 本质就是一种规范格式的 Token,以.分割,Header.Payload.Signature
# md5属于哈希,只加密不解密,严格来说不算加密方式
import hashlib
import time
import hmac
import hashlib
# Sign签名加密
class SignUtil:
    # 后端给你的密钥(每个项目不一样)
    SECRET = "PROJECT_SECRET_2025"
    @classmethod
    def make_sign(cls, params: dict) -> str:
        """
        企业标准签名生成
        :param params: 接口参数
        :return: sign 签名
        """
        # 1. 按key排序(必须!) params.items()拿到字典中的键值对,转化成列表
        # params  # 字典:{'name': '张三', 'age': 18}
        # params.keys()  # 只有键:['name', 'age']
        # params.values()  # 只有值:['张三', 18]
        # params.items()  # 键+值:[('name', '张三'), ('age', 18)]
        sorted_items = sorted(params.items())

        # 2. 拼接成 key=value&key=value for k, v in sorted_items取出key,value值,按照"{k}={v}"拼接,用&将其连起来
        temp_str = "&".join([f"{k}={v}" for k, v in sorted_items])

        # 3. 拼接密钥
        temp_str += f"&secret={cls.SECRET}"

        # 4. MD5 加密
        md5 = hashlib.md5(temp_str.encode("utf-8"))
        return md5.hexdigest().upper()  # 大部分企业要求大写

    @classmethod
    def timestamp(cls) -> str:
        """时间戳:防重复请求"""
        return str(int(time.time()))


# HMAC-SHA256 签名
class HmacSha256:
    SECRET_KEY = "your_project_secret_key_here"

    @classmethod
    def sign(cls, data: dict) -> str:
        """
        企业标准 HMAC-SHA256 签名
        """
        # 1. 按 key 排序
        sorted_items = sorted(data.items())
        # 2. 拼接成无连接字符串(项目不同格式略有差异)
        plain_text = "".join([f"{k}{v}" for k, v in sorted_items])

        # 3. HMAC-SHA256 加密
        hmac_obj = hmac.new(
            key=cls.SECRET_KEY.encode("utf-8"),
            msg=plain_text.encode("utf-8"),
            digestmod=hashlib.sha256
        )

        # 4. 转16进制小写(企业常用)
        return hmac_obj.hexdigest().lower()


# AES对称加密  pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
class AesUtil:
    # 后端给你的 16 位密钥(128位)
    KEY = "1234567890123456"
    IV  = "abcdefghijklmnop"

    @classmethod
    def encrypt(cls, text: str) -> str:
        """加密:明文 → 密文"""
        aes = AES.new(cls.KEY.encode(), AES.MODE_CBC, cls.IV.encode())
        padded = pad(text.encode('utf-8'), AES.block_size)
        encrypted = aes.encrypt(padded)
        return base64.b64encode(encrypted).decode()

    @classmethod
    def decrypt(cls, base64_cipher: str) -> str:
        """解密:密文 → 明文"""
        aes = AES.new(cls.KEY.encode(), AES.MODE_CBC, cls.IV.encode())
        encrypted = base64.b64decode(base64_cipher)
        decrypted = aes.decrypt(encrypted)
        unpadded = unpad(decrypted, AES.block_size)
        return unpadded.decode('utf-8')


from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64
# RSA非对称加密
class RsaUtil:
    # 后端给你的公钥(固定写这里)
    PUBLIC_KEY = """
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...
-----END PUBLIC KEY-----
"""

    @classmethod
    def encrypt(cls, text: str) -> str:
        """RSA 公钥加密"""
        pub_key = RSA.importKey(cls.PUBLIC_KEY)
        cipher = PKCS1_v1_5.new(pub_key)
        encrypted = cipher.encrypt(text.encode("utf-8"))
        return base64.b64encode(encrypted).decode()

# JWT鉴权 pip install pyjwt
import jwt
class JwtUtil:
    # 密钥,后端提供
    SECRET = "JWT_SECRET_2026"
    ALGORITHM = "HS256"

    @classmethod
    def encode(cls, payload: dict) -> str:
        """生成 JWT"""
        return jwt.encode(payload, cls.SECRET, algorithm=cls.ALGORITHM)

    @classmethod
    def decode(cls, token: str) -> dict:
        """解析 JWT"""
        return jwt.decode(token, cls.SECRET, algorithms=[cls.ALGORITHM])