数据安全是我们开发者一直关心的问题,为了加强传输安全,防止中间人劫持,https就诞生了。为了防止数据明文,各种加密算法出来了。下面分别介绍常用的加密,对称加密(AES)与非对称加密(RSA)。下面代码是执行在python3.7

AES 加密

1
pip3 install pycrypto
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from Crypto.Cipher import AES
from base64 import b64encode, decodebytes


class AESCipher:
    KEY = "0zQB4KtToVx13p9a"
    BLOCK_SIZE = 16  # Bytes
    
    def __new__(cls, *args, **kwargs):
        # 单例初始化AES.new方法
        if not hasattr(cls, '_instance'):
            cls.cipher = AES.new(cls.KEY, AES.MODE_ECB)
            cls._instance = super(AESCipher, cls).__new__(cls, *args, **kwargs)
        return cls._instance

    @staticmethod
    def pad_string(string: str) -> str:
        # 填充
        return string + (AESCipher.BLOCK_SIZE - len(string) % AESCipher.BLOCK_SIZE) * chr(
            AESCipher.BLOCK_SIZE - len(string) % AESCipher.BLOCK_SIZE)

    def encrypt(self, raw: str) -> str:
        raw = self.pad_string(raw)
        return b64encode(self.cipher.encrypt(raw)).decode('utf8')

    def decrypt(self, enc: bytes) -> str:
        try:
            if not enc:
                return ''
            dec_str = self.cipher.decrypt(decodebytes(enc))
            return dec_str[:-ord(dec_str[len(dec_str) - 1:])].decode('utf8')
        except ValueError:
            return ''
            


import json

enc_ss = json.dumps({'a': 123})
es = AESCipher().encrypt(enc_ss)
print(es)

b2 = bytes(es, encoding="utf8")
print(AESCipher().decrypt(b2))

RSA 加密

1
pip3 install rsa
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
import rsa
import base64
from typing import Any

import json


class RSACipher:
    PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDASH8+mT3KIiB7bk2qtegLDfRRZLZayllvvx6toGi5XswsBJpU
L9VqYsAfF8L265h4PHVp7tVY0/K7r4BzwfNe5OVcv5n6H5EKwhZ0tU+fyHMUOJu8
Q/aWYtLlf9MWII5jzhxj7waOyMtfhTTCw3Pa/x3Tns5lcgCV6Ny5F4l3IQIDAQAB
AoGARAtjvCtOinF5PTTTl024R/EwPH1/arGg5MKlgJv7c13wssMOOiyTQYqgomAu
RmMpGaOLiWlTZpPamkCJHG3OSXFyCbpsuOqQa7BLDLAZIxo4eVluWxT93DXW7CE2
bj29Zx7/R/6n2t5hobb5PhfLIsWffeVUg4p8ccnsWx13wAECQQDjvWqtaGwOBvKl
p+y8aMFL96yc+I337/zkF1bNWtoNbSPIfCwOKdoBL4GgTZjIkrfXbnyHshJEqQao
2cegK4BhAkEA2CS7RZreFPf3bgps09ZSCsrXS17ILYy5PpZycAj5iLay8r71wnyG
FcxvJr8xkBqCE3AS8/ApgfCMFsr9XhRuwQJAdJCW8XrpE6TqvW9d9HGJvmBesVln
EOh9ACISA7nkscqS7iLgSb+SHdk699m/wamW/2VFyA6U2x/IkNQnIQwjAQJBAJmc
2V+ppiY+6SHS1O9lBV/YM1TEov4EYm9B20kWh8oLFnkBEIbNmzoI1gIypdXlkQah
g0bNK6LGw7k7QQDJAsECQQCyubO7Lhfl+nrzTbrqbb7lRqZIcylOnNEzFmF5Sz1Y
6O9Ln6qc2AuvA2ZcXNI8+Xwbt09m5Psbz77UCmO+l5Uf
-----END RSA PRIVATE KEY-----"""
    PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDASH8+mT3KIiB7bk2qtegLDfRR
ZLZayllvvx6toGi5XswsBJpUL9VqYsAfF8L265h4PHVp7tVY0/K7r4BzwfNe5OVc
v5n6H5EKwhZ0tU+fyHMUOJu8Q/aWYtLlf9MWII5jzhxj7waOyMtfhTTCw3Pa/x3T
ns5lcgCV6Ny5F4l3IQIDAQAB
-----END PUBLIC KEY-----"""

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls.privkey = rsa.PrivateKey.load_pkcs1(cls.PRIVATE_KEY.encode())
            cls.pubkey = rsa.key.PublicKey.load_pkcs1_openssl_pem(cls.PUBLIC_KEY.encode())
            cls._instance = super(RSACipher, cls).__new__(cls, *args, **kwargs)
        return cls._instance

    @staticmethod
    def params_sort(params: dict) -> str:
        """
        参数 按照ASCII排序
        :param params: 参数dict
        :return: dict
        """
        params = sorted(params.items(), key=lambda item: item[0], reverse=False)
        return '&'.join([key + '=' + str(val) for key, val in params if key != 'sign'])

    def sign(self, params: dict) -> str:
        """
        获取签名
        :param params: 加签数据
        :return: str
        """
        params_str = RSACipher.params_sort(params)
        sign = rsa.sign(params_str.encode(), self.privkey, 'SHA-1')
        return base64.b64encode(sign).decode()

    def verify_sign(self, params: dict) -> bool:
        """
        签名验证
        :param pubkey: pubkey验证
        :param params: 验证数据
        :return: bool
        """
        try:
            sign = params.get('sign')
            params_str = RSACipher.params_sort(params)
            rsa.verify(params_str.encode(), base64.b64decode(sign), self.pubkey)
            return True
        except Exception as e:
            print(e)
            return False

    def encrypt(self, params: str) -> str:
        """
        数据公钥加密
        :param pubkey: pubkey加密
        :param params: 加密数据
        :return: data
        """
        encrypt_str = rsa.encrypt(params.encode(), self.pubkey)
        return base64.b64encode(encrypt_str).decode()

    def decrypt(self, sign: str) -> Any:
        """
        数据私钥解密
        :param sign: 带解密字符串
        :return:
        """
        try:
            res = rsa.decrypt(base64.b64decode(sign), self.privkey)
            if isinstance(res, bytes):
                res = res.decode()
            return res
        except Exception as e:
            print(e)
            return None


print("#######加解签#######")
body = {"a": 123}
sign_str = RSACipher().sign(body)
body['sign'] = sign_str
print(RSACipher().verify_sign(body))


print("#######加解密#######")
body = {"a": 123}
r = sign_str = RSACipher().encrypt(json.dumps(body))
print(r)
print(RSACipher().decrypt(r))