├── AES.py └── README.md /AES.py: -------------------------------------------------------------------------------- 1 | # _*_ coding: utf-8 _*_ 2 | # @Time:2022/3/11 5:25 下午 3 | # @Author:YwY(慕白) 4 | # @File:AES.py 5 | 6 | import hashlib, base64 7 | from Crypto.Cipher import AES 8 | from cryptography.hazmat.primitives.padding import PKCS7 9 | from cryptography.hazmat.primitives.ciphers import algorithms 10 | import json 11 | 12 | def pkcs7padding(text): 13 | """ 14 | 明文使用PKCS7填充 15 | 最终调用AES加密方法时,传入的是一个byte数组,要求是16的整数倍,因此需要对明文进行处理 16 | :param text: 待加密内容(明文) 17 | :return: 18 | """ 19 | bs = AES.block_size # 16 20 | length = len(text) 21 | bytes_length = len(bytes(text, encoding='utf-8')) 22 | # tips:utf-8编码时,英文占1个byte,而中文占3个byte 23 | padding_size = length if (bytes_length == length) else bytes_length 24 | padding = bs - padding_size % bs 25 | # tips:chr(padding)看与其它语言的约定,有的会使用'\0' 26 | padding_text = chr(padding) * padding 27 | return text + padding_text 28 | 29 | 30 | def pkcs7_unpad(content): 31 | """ 32 | 解密时候用 33 | :param content: 34 | :return: 35 | """ 36 | if not isinstance(content, bytes): 37 | content = content.encode() 38 | pad = PKCS7(algorithms.AES.block_size).unpadder() 39 | pad_content = pad.update(content) + pad.finalize() 40 | return pad_content 41 | 42 | 43 | def encrypt(key, content): 44 | """ 45 | AES加密 46 | key,iv使用同一个 47 | 模式cbc 48 | 填充pkcs7 49 | :param key: 密钥 50 | :param content: 加密内容 51 | :return: 52 | """ 53 | key_bytes = bytes(key, encoding='utf-8') 54 | iv = key_bytes 55 | cipher = AES.new(key_bytes, AES.MODE_ECB) 56 | # 处理明文 57 | content_padding = pkcs7padding(content) 58 | # 加密 59 | encrypt_bytes = cipher.encrypt(bytes(content_padding, encoding='utf-8')) 60 | # 重新编码 61 | result = str(base64.b64encode(encrypt_bytes), encoding='utf-8') 62 | return result 63 | 64 | def decrypt(key,text): 65 | key_bytes = bytes(key, encoding='utf-8') 66 | iv = key_bytes 67 | cryptos = AES.new(key_bytes, AES.MODE_ECB) 68 | data = cryptos.decrypt(text) 69 | return json.loads(pkcs7_unpad(data)) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `都是作者累积的,且看其珍惜,大家可以尽量可以保存一下,如果转载请写好出处https://www.cnblogs.com/pythonywy` 2 | 3 | `git地址https://github.com/a568972484/The_encryption_template_Python` 4 | 5 | ## 一.md5加密 6 | 7 | ### 1.简介 8 | 9 | `这是一种使用非常广泛的加密方式,不可逆的,常见16位和32位一般都是md5` 10 | 11 | ```python 12 | import hashlib 13 | 14 | data = '你好' 15 | print(hashlib.md5(data.encode(encoding="UTF-8")).hexdigest()) #32位 16 | print(hashlib.md5(data.encode(encoding="UTF-8")).hexdigest()[8:-8]) #16位 17 | ``` 18 | 19 | ## 二.RSA加密 20 | 21 | ### 1.简介 22 | 23 | `非对称加密算法,也就是比较常见的公钥私钥加密,可逆的` 24 | 25 | ### 2.指数和模加密无填充-模板一 26 | 27 | ```python 28 | import rsa 29 | #模 30 | m = "ae068c2039bd2d82a529883f273cf20a48e0b6faa564e740402375a9cb332a029b8492ae342893d9c9d53d94d3ab8ae95de9607c2e03dd46cebe211532810b73cc764995ee61ef435437bcddb3f4a52fca66246dbdf2566dd85fbc4930c548e7033c2bcc825b038e8dd4b3553690e0c438bbd5ade6f5a476b1cbc1612f5d501f" 31 | #指数 32 | e = '10001' 33 | #加密参数 34 | message = '123456' 35 | 36 | class Encrypt(object): 37 | def __init__(self, e, m): 38 | self.e = e 39 | self.m = m 40 | 41 | def encrypt(self, message): 42 | mm = int(self.m, 16) 43 | ee = int(self.e, 16) 44 | rsa_pubkey = rsa.PublicKey(mm, ee) 45 | crypto = self._encrypt(message.encode(), rsa_pubkey) 46 | return crypto.hex() 47 | 48 | def _pad_for_encryption(self, message, target_length): 49 | message = message[::-1] 50 | max_msglength = target_length - 11 51 | msglength = len(message) 52 | 53 | padding = b'' 54 | padding_length = target_length - msglength - 3 55 | 56 | for i in range(padding_length): 57 | padding += b'\x00' 58 | 59 | return b''.join([b'\x00\x00', padding, b'\x00', message]) 60 | 61 | def _encrypt(self, message, pub_key): 62 | keylength = rsa.common.byte_size(pub_key.n) 63 | padded = self._pad_for_encryption(message, keylength) 64 | 65 | payload = rsa.transform.bytes2int(padded) 66 | encrypted = rsa.core.encrypt_int(payload, pub_key.e, pub_key.n) 67 | block = rsa.transform.int2bytes(encrypted, keylength) 68 | 69 | return block 70 | 71 | if __name__ == '__main__': 72 | en = Encrypt(e, m) 73 | print(en.encrypt(message)) 74 | ``` 75 | 76 | ### 3.指数和模加密无填充-模板二 77 | 78 | ```python 79 | import codecs 80 | 81 | def rsa_encrypt(content): 82 | public_exponent = '010001' 83 | public_modulus = 'ae068c2039bd2d82a529883f273cf20a48e0b6faa564e740402375a9cb332a029b8492ae342893d9c9d53d94d3ab8ae95de9607c2e03dd46cebe211532810b73cc764995ee61ef435437bcddb3f4a52fca66246dbdf2566dd85fbc4930c548e7033c2bcc825b038e8dd4b3553690e0c438bbd5ade6f5a476b1cbc1612f5d501f' 84 | 85 | content = content[::-1] 86 | rsa = int(codecs.encode(content.encode('utf-8'), 'hex_codec'), 87 | 16) ** int(public_exponent, 16) % int(public_modulus, 16) 88 | # 把10进制数rsa转为16进制('x'表示16进制),再取前256位,不够的在最前面补0 89 | return format(rsa, 'x').zfill(256) 90 | ``` 91 | 92 | ### 4.指数和模加密无填充-模板三 93 | 94 | ```python 95 | import math 96 | if __name__ == '__main__': 97 | # 实为16进制串,前补0 98 | e = '' 99 | # m也需要补00 100 | m = '008eb933413be3234dddd2730fbb1d05c8848a43d5dc3bdd997f2a9935fba6beb9ffb36854482b0b46cf7e6f9afbbe2e2e7d606fde20bec57dbf722e7985192e8813e6b67628a6f202cf655b7d2ffce4e9dc682dd6034ae706c8e255f25e4051b9ca43f25b3ad686aac9c8f6aeb71d921c13a255c806f78a5a7b9a356c2dd274e3' 101 | m = int.from_bytes(bytearray.fromhex(m), byteorder='big') 102 | e = int.from_bytes(bytearray.fromhex(e), byteorder='big') 103 | # js加密为反向,为保持一致原文应反向处理,所以这里原文实际为204dowls 104 | plaintext = 'slwod402'.encode('utf-8') 105 | # 无填充加密逻辑 106 | input_nr = int.from_bytes(plaintext, byteorder='big') 107 | crypted_nr = pow(input_nr, e, m) 108 | keylength = math.ceil(m.bit_length() / 8) 109 | crypted_data = crypted_nr.to_bytes(keylength, byteorder='big') 110 | print(crypted_data.hex()) 111 | ``` 112 | 113 | ### 5.指数和模加密有填充 114 | 115 | ```python 116 | from cryptography.hazmat.backends import default_backend 117 | from cryptography.hazmat.primitives.asymmetric import rsa 118 | from cryptography.hazmat.primitives.asymmetric import padding 119 | import base64 120 | import binascii 121 | 122 | """ 123 | 另种rsa加密 124 | """ 125 | 126 | 127 | def data_encrypt(text): 128 | """ 129 | RSA 加密 130 | :param text: 加密前内容 131 | :return: 加密后内容 132 | """ 133 | # 判断系统,加载指定模块 134 | public_exponent = int("010001",16) #指数 135 | print(public_exponent) 136 | public_modulus=int('B23322F080BD5876C0735D585D25C7BC409F637237B07744D27FBF39FB100ABE59DF380EA6BFCDF28C286E7A0CD95BE87F6099F8F39B0E97D9782C3D33FCFB80D43D2F22A9D9417ECFD1A0B8421DEE1CD4B323E8078336E77419A97F94E60A90CA06551202F63819FC8E73425F06ECA4C05BBF8CA32366240A6C36CA61D85019',16) #模 137 | # content = 'leadeon' + text + time.strftime("%Y%m%d%H%M%S", time.localtime()) 138 | content = text 139 | max_length = 117 140 | # public_key = serialization.load_pem_public_key(key, backend=default_backend()) 141 | public_key = rsa.RSAPublicNumbers(public_exponent, public_modulus).public_key(default_backend()) 142 | data = b'' 143 | for i in range(0, len(content), max_length): 144 | data += public_key.encrypt(content[i: i + max_length].encode(), 145 | padding.PKCS1v15()) 146 | data = base64.b64encode(data).decode() 147 | #data =binascii.b2a_hex(data).decode() hex输出 148 | return data 149 | ``` 150 | 151 | ### 6.公钥加密 152 | 153 | ```python 154 | # 公钥加密 155 | import base64 156 | import rsa 157 | from Crypto.PublicKey import RSA 158 | 159 | def encryptPassword(data, publicKeyStr): 160 | ''' 161 | data:内容 162 | publicKeyStr:不需要-----BEGIN PUBLIC KEY-----开头,-----END PUBLIC KEY-----结尾的格式,只要中间部分即可 163 | key_encoded:需要-----BEGIN PUBLIC KEY-----开头,-----END PUBLIC KEY-----结尾的格式 164 | ''' 165 | key_encoded='''-----BEGIN PUBLIC KEY----- 166 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdZGziIrJOlRomzh7M9qzo4ibw 167 | QmwORcVDI0dsfUICLUVRdUN+MJ8ELd55NKsfYy4dZodWX7AmdN02zm1Gk5V5i2Vw 168 | GVWE205u7DhtRe85W1oR9WTsMact5wuqU6okJd2GKrEGotgd9iuAJm90N6TDeDZ4 169 | KHEvVEE1yTyvrxQgkwIDAQAB 170 | -----END PUBLIC KEY-----''' 171 | # 1、base64解码 172 | publicKeyBytes = base64.b64decode(publicKeyStr.encode()) 173 | # 3、生成publicKey对象 174 | key = RSA.import_key(publicKeyBytes) 175 | #key = RSA.import_key(key_encoded) 176 | # 4、对原密码加密 177 | encryptPassword = rsa.encrypt(data.encode(), key) 178 | return base64.b64encode(encryptPassword).decode() 179 | ``` 180 | 181 | ### 7.私钥解密 182 | 183 | ```python 184 | # rsa 解密 185 | def long_decrypt(msg): 186 | rsa_private_key = """-----BEGIN RSA PRIVATE KEY----- 187 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQClceuXNXcT7H8ElMfzfRhgOoxqmINR7LGXk+tUrIHHP8VCJfqxTKmow45dNK+kfBRKT9+uSxFlNV5uBdfaBFX13Eq8Ynq12hgvILYihU0gUNVuESTdFGaSS60AaCbuPpD9ENVgs4hrHfJwD4PWXCSpoPPcw9s4DSsxmapcHdE8hR21uWeEbQKISrZe+wdqI5Bv+iVqqd6MbX+pO3QJ4CcmVILomAEn64dHqP1cmRZaZ59J/Y9aP9qYtiPYO0kArsxVDM6ZWkDyrbjJJcbaPBmi4JppNTD/fRhDrSdRn8CBTZEnqRKLANhb4V+qaPaU9wAOWDwJqcT18RjfTcuxWi/zAgMBAAECggEAIBabUgWNpfCdph7RNTmTC77vUxFnjvEwdKy83PxkY2fL84t4NwEeetwK9artUiK6sLsTMDPhGNckDITXm7JxlbD3Udhr4m99d06J5OIj1lu3OZTbqIF3b3J8CHMq8dRyvJKSQCIyGEyDpBZuRJo0hi3wfmYCU7nCIemi8CDcXzdGXTaRdiAW73nn+Ow8sFX+XG6/6hPw9t+0r8GhrEfknC29NIPtAQqjamrKQm4lcW9eClId7vknZoNXsWw7w3B1pHy71GDFs+wquG8A3GjHOwySptrb0XexzwEzuxR0HJOdKrsNRSUncm0eY6lfQNW0PEN6IXopK0DooyCQO00rCQKBgQDZAEL6zDXPctCaPtS8qifd/hN3aMz+XvX+O811sXYaB/5ySndaR3mApJnbcoYDvL3EvFWL3YgjWL8Qp0HX7gTrdDuOv8yY+K2i347CCU+B0E81gP1tvUCVTc3x+hLKgcOs8UDH+GouLe1qycVs2FliuYngUFaZwOX4H4MFMiTgdQKBgQDDLa4JsnwY7kR88TLteEqC2G6Jk9IPRMut/PDvdrGHyj6YEw7WbZLnyAMOEm1NeTa+bIr8mPPEEM1mrS3xaWwgn1rMqqzkSC/DpgFppiJGBGX6cDFs2fYJOFBMzKlGIoHcWdl1SSEYbzxNo5ljoK6r+UaBfMcuuS5BHQ56nKpBxwKBgF2Lu1QajGftevfDdjoOsDkGuqWTTCusDCeY6C2AXwVBxPLIH0OP5FUMoDb128foqXYSKl6tFW8HZvZq4/uN5BkMdlBHZo/bRB8eeJA1K00u27aY8KdKGnlCnTFfOJKL9iqrpd2OvVdC/UI30R/m9EGW8lT8zRhjC8A29WhcAYGxAoGAA9U20LvvkfHD6Iw4Cs/M7srfSNZdTq10LoOEG7/B9r+zAPuG1BEszF5yKOmVuerCd3TcOd+rEdOepQCLoW0HkZBvkQtc/9KnFXmCF5gKnkNh2UwwvEl/emjfstJmFJmC4VfmXFZGTxuIHKI01e8G3xuzFcHki3dZgC/Y4/GFqmsCgYBvQbz9raUVVxJwkN+9UsciTNzW10Tkt2OLYlFRiD+QAC9XK7ZjrjIkQIXEL5OrzYDTU3aHNWt3QwZskSfwFD4P118ICkVdPI9If/I0iqtQwCoIM83dtTFhJrImq0zxFn/dxhJv6ga+/CqJQmLHXMWt+vtvlSgcosvU3eYlVpoPjQ== 188 | -----END RSA PRIVATE KEY-----""" 189 | msg = base64.b64decode(msg) 190 | # 私钥解密 191 | priobj = Cipher_pkcs1_v1_5.new(RSA.importKey(rsa_private_key)) 192 | data = priobj.decrypt(msg,None).decode() 193 | return data 194 | ``` 195 | 196 | ### 8..验签 197 | 198 | ```python 199 | from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5 200 | from Crypto.Signature import PKCS1_v1_5 201 | 202 | from Crypto.PublicKey import RSA 203 | from Crypto.Hash import SHA256 204 | import base64 205 | 206 | 207 | class RsaUtil: 208 | 209 | def __init__(self, pub_key, pri_key): 210 | self.pri_key_obj = None 211 | self.pub_key_obj = None 212 | self.verifier = None 213 | self.signer = None 214 | if pub_key: 215 | pub_key = RSA.importKey(base64.b64decode(pub_key)) 216 | self.pub_key_obj = Cipher_pkcs1_v1_5.new(pub_key) 217 | self.verifier = PKCS1_v1_5.new(pub_key) 218 | if pri_key: 219 | pri_key = RSA.importKey(base64.b64decode(pri_key)) 220 | self.pri_key_obj = Cipher_pkcs1_v1_5.new(pri_key) 221 | self.signer = PKCS1_v1_5.new(pri_key) 222 | 223 | def public_long_encrypt(self, data, charset='utf-8'): 224 | data = data.encode(charset) 225 | length = len(data) 226 | default_length = 117 227 | res = [] 228 | for i in range(0, length, default_length): 229 | res.append(self.pub_key_obj.encrypt(data[i:i + default_length])) 230 | byte_data = b''.join(res) 231 | return base64.b64encode(byte_data) 232 | 233 | def private_long_decrypt(self, data, sentinel=b'decrypt error'): 234 | data = base64.b64decode(data) 235 | length = len(data) 236 | default_length = 128 237 | res = [] 238 | for i in range(0, length, default_length): 239 | res.append(self.pri_key_obj.decrypt(data[i:i + default_length], sentinel)) 240 | return str(b''.join(res), encoding = "utf-8") 241 | 242 | def sign(self, data, charset='utf-8'): 243 | h = SHA256.new(data.encode(charset)) 244 | signature = self.signer.sign(h) 245 | return base64.b64encode(signature) 246 | 247 | def verify(self, data, sign, charset='utf-8'): 248 | h = SHA256.new(data.encode(charset)) 249 | return self.verifier.verify(h, base64.b64decode(sign)) 250 | 251 | ``` 252 | 253 | #### 8.1MD5withRSA 签名 254 | 255 | ```python 256 | from Crypto.PublicKey import RSA 257 | from Crypto.Signature import PKCS1_v1_5 258 | from Crypto.Hash import MD5, SHA1, SHA256 259 | import base64 260 | from flask import current_app 261 | import warnings 262 | warnings.filterwarnings("ignore") 263 | 264 | 265 | 266 | def RSA_sign(data): 267 | privateKey = '''MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIooE+9hmb6GvAUQ3j9FDRgrhWMmVWKepKNmQerrvovmySUSPzFHainDMl6HuQAWHCMI9O8S9kzqG3o9pnetpG7JShB6Oc9eX0kA6n0vLR2rYXNo5uVC29/Koqp250T7lzQ9bv6P0rkjIrqjTNIPVQXToyAwQcZQ5rVhUbtnP7YlAgMBAAECgYBpSzpGS0B9sPpDciOwXNQqA6FZe7G/w+D+l8TNYnaK8Y2Dr3ByAlerFJWi7hXVNwSivwTN4MnOvO3MMIha1gBnQCFStI4PjRv2qz6vsGfzZKFadUw3ngzGhT5UtIVAd+IFbbr4J+cGjGMmF5lIEaKrRCS5u4p11uf6LmhvbBTm0QJBAMQA7RYimdU9UStIm/RSkLQg6K89Om3S2AFXwqymiqhM4m6n7lRTE1xNX4pGm1BV8C/qL0d7AHbrJBFi+hN5onMCQQC0cjAXmKdnfhTo0IvYtzpXr77odBz4zt2Ake65ssBJEWFzle69MbWgkbrTKLLjGxBwM+C7fPDGNckqhlpjMGcHAkB+vcKRT6p9svqrrHX8FO+xKp6LwmHn5jD7HU6q6b47egvpVfnM2TNpujaPaXzBA/EeaqZL6IOyYfaer4vZ0At1AkEAqezuRQpIezlMT4I0b7z8gB7MVPMjZVrJVI4YlV8znJt1ffevfxMUy0Tw/nDRJPUTodX4yBZ8VuvHqPgknkuyeQJBALYpXGOH/GjlSVtnhq7eZxvoEqiBLawW5k7Rl1IyNdGR2qxY/nnoCyP2mMCs1Ba05sCcX08zzOzMPvttbSyjqPI=''' 268 | 269 | private_keyBytes = base64.b64decode(privateKey) 270 | priKey = RSA.importKey(private_keyBytes) 271 | # priKey = RSA.importKey(privateKey) 272 | signer = PKCS1_v1_5.new(priKey,) 273 | # SIGNATURE_ALGORITHM = "MD5withRSA" 274 | hash_obj = MD5.new(data.encode('utf-8')) 275 | # SIGNATURE_ALGORITHM = "SHA1withRSA" 276 | # hash_obj = SHA1.new(data.encode('utf-8')) 277 | # SIGNATURE_ALGORITHM = "SHA256withRSA" 278 | # hash_obj = SHA256.new(data.encode('utf-8')) 279 | 280 | signature = base64.b64encode(signer.sign(hash_obj)) 281 | return signature 282 | 283 | 284 | if __name__ == '__main__': 285 | data = "phone=15811352072×tamp=1612496512540&device=Android" 286 | res_sign1 = RSA_sign(data) 287 | signature = res_sign1.decode('utf8') 288 | print(signature) 289 | ``` 290 | 291 | #### 8.2实现SHA1withRSA 签名 292 | 293 | ```python 294 | from Crypto.PublicKey import RSA 295 | from Crypto.Signature import PKCS1_v1_5 296 | from Crypto.Hash import MD5, SHA1, SHA256 297 | import base64 298 | from flask import current_app 299 | import warnings 300 | warnings.filterwarnings("ignore") 301 | 302 | 303 | 304 | def RSA_sign(data): 305 | privateKey = '''MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIooE+9hmb6GvAUQ3j9FDRgrhWMmVWKepKNmQerrvovmySUSPzFHainDMl6HuQAWHCMI9O8S9kzqG3o9pnetpG7JShB6Oc9eX0kA6n0vLR2rYXNo5uVC29/Koqp250T7lzQ9bv6P0rkjIrqjTNIPVQXToyAwQcZQ5rVhUbtnP7YlAgMBAAECgYBpSzpGS0B9sPpDciOwXNQqA6FZe7G/w+D+l8TNYnaK8Y2Dr3ByAlerFJWi7hXVNwSivwTN4MnOvO3MMIha1gBnQCFStI4PjRv2qz6vsGfzZKFadUw3ngzGhT5UtIVAd+IFbbr4J+cGjGMmF5lIEaKrRCS5u4p11uf6LmhvbBTm0QJBAMQA7RYimdU9UStIm/RSkLQg6K89Om3S2AFXwqymiqhM4m6n7lRTE1xNX4pGm1BV8C/qL0d7AHbrJBFi+hN5onMCQQC0cjAXmKdnfhTo0IvYtzpXr77odBz4zt2Ake65ssBJEWFzle69MbWgkbrTKLLjGxBwM+C7fPDGNckqhlpjMGcHAkB+vcKRT6p9svqrrHX8FO+xKp6LwmHn5jD7HU6q6b47egvpVfnM2TNpujaPaXzBA/EeaqZL6IOyYfaer4vZ0At1AkEAqezuRQpIezlMT4I0b7z8gB7MVPMjZVrJVI4YlV8znJt1ffevfxMUy0Tw/nDRJPUTodX4yBZ8VuvHqPgknkuyeQJBALYpXGOH/GjlSVtnhq7eZxvoEqiBLawW5k7Rl1IyNdGR2qxY/nnoCyP2mMCs1Ba05sCcX08zzOzMPvttbSyjqPI=''' 306 | 307 | private_keyBytes = base64.b64decode(privateKey) 308 | priKey = RSA.importKey(private_keyBytes) 309 | # priKey = RSA.importKey(privateKey) 310 | signer = PKCS1_v1_5.new(priKey,) 311 | # SIGNATURE_ALGORITHM = "MD5withRSA" 312 | # hash_obj = MD5.new(data.encode('utf-8')) 313 | # SIGNATURE_ALGORITHM = "SHA1withRSA" 314 | hash_obj = SHA1.new(data.encode('utf-8')) 315 | # SIGNATURE_ALGORITHM = "SHA256withRSA" 316 | # hash_obj = SHA256.new(data.encode('utf-8')) 317 | 318 | signature = base64.b64encode(signer.sign(hash_obj)) 319 | return signature 320 | 321 | if __name__ == '__main__': 322 | data = "phone=15811352072×tamp=1612496512540&device=Android" 323 | res_sign1 = RSA_sign(data) 324 | signature = res_sign1.decode('utf8') 325 | print(signature) 326 | ``` 327 | 328 | #### 8.3SHA256withRSA签名 329 | 330 | ```python 331 | from Crypto.PublicKey import RSA 332 | from Crypto.Signature import PKCS1_v1_5 333 | from Crypto.Hash import MD5, SHA1, SHA256 334 | import base64 335 | from flask import current_app 336 | import warnings 337 | warnings.filterwarnings("ignore") 338 | 339 | 340 | 341 | def RSA_sign(data): 342 | privateKey = '''MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAIooE+9hmb6GvAUQ3j9FDRgrhWMmVWKepKNmQerrvovmySUSPzFHainDMl6HuQAWHCMI9O8S9kzqG3o9pnetpG7JShB6Oc9eX0kA6n0vLR2rYXNo5uVC29/Koqp250T7lzQ9bv6P0rkjIrqjTNIPVQXToyAwQcZQ5rVhUbtnP7YlAgMBAAECgYBpSzpGS0B9sPpDciOwXNQqA6FZe7G/w+D+l8TNYnaK8Y2Dr3ByAlerFJWi7hXVNwSivwTN4MnOvO3MMIha1gBnQCFStI4PjRv2qz6vsGfzZKFadUw3ngzGhT5UtIVAd+IFbbr4J+cGjGMmF5lIEaKrRCS5u4p11uf6LmhvbBTm0QJBAMQA7RYimdU9UStIm/RSkLQg6K89Om3S2AFXwqymiqhM4m6n7lRTE1xNX4pGm1BV8C/qL0d7AHbrJBFi+hN5onMCQQC0cjAXmKdnfhTo0IvYtzpXr77odBz4zt2Ake65ssBJEWFzle69MbWgkbrTKLLjGxBwM+C7fPDGNckqhlpjMGcHAkB+vcKRT6p9svqrrHX8FO+xKp6LwmHn5jD7HU6q6b47egvpVfnM2TNpujaPaXzBA/EeaqZL6IOyYfaer4vZ0At1AkEAqezuRQpIezlMT4I0b7z8gB7MVPMjZVrJVI4YlV8znJt1ffevfxMUy0Tw/nDRJPUTodX4yBZ8VuvHqPgknkuyeQJBALYpXGOH/GjlSVtnhq7eZxvoEqiBLawW5k7Rl1IyNdGR2qxY/nnoCyP2mMCs1Ba05sCcX08zzOzMPvttbSyjqPI=''' 343 | 344 | private_keyBytes = base64.b64decode(privateKey) 345 | priKey = RSA.importKey(private_keyBytes) 346 | # priKey = RSA.importKey(privateKey) 347 | signer = PKCS1_v1_5.new(priKey,) 348 | # SIGNATURE_ALGORITHM = "MD5withRSA" 349 | # hash_obj = MD5.new(data.encode('utf-8')) 350 | # SIGNATURE_ALGORITHM = "SHA1withRSA" 351 | # hash_obj = SHA1.new(data.encode('utf-8')) 352 | # SIGNATURE_ALGORITHM = "SHA256withRSA" 353 | hash_obj = SHA256.new(data.encode('utf-8')) 354 | 355 | signature = base64.b64encode(signer.sign(hash_obj)) 356 | return signature 357 | 358 | if __name__ == '__main__': 359 | data = "phone=15811352072×tamp=1612496512540&device=Android" 360 | res_sign1 = RSA_sign(data) 361 | signature = res_sign1.decode('utf8') 362 | print(signature) 363 | ``` 364 | 365 | ### 9.最原始方法生成公钥和私钥生成通过(crtCoefficient,primeExponentP,primeP,modulus.....) 366 | 367 | ```python 368 | from cryptography.hazmat.backends import default_backend 369 | from cryptography.hazmat.primitives.asymmetric import rsa 370 | from cryptography.hazmat.primitives import serialization 371 | from cryptography.hazmat.primitives.asymmetric import padding 372 | import base64 373 | import binascii 374 | 375 | """ 376 | "crtCoefficient": 84432856058147832764138703472538317942464795044718601494587194148378563942685, 377 | "primeExponentP": 55430473883101152246097615323756881862950432952434504984590276578045386834041, 378 | "primeExponentQ": 41230473446336148758497170998210312513410109720579275453308960734626604833351, 379 | "primeP": 109910049826842557628963433845850622251367013324570378590557090526907918339059, 380 | "primeQ": 106061213575088596820097699717773256317123615840075518129430834072505546216719, 381 | "publicExponent": 65537, 382 | "modulus": 11657193268733377953496174345085266431511790176736829620324311319483544845433376888008449023832068012445414318729055242605500539982129558003843075736527421, 383 | "privateExponent": 3398954883077133822319581237472486629533832773658606240974980011352534575146593099441248529746198644134125073285288483505741834384822184028018785454859181 384 | """ 385 | 386 | 387 | 388 | def gen_rsa_keypair(): 389 | d = 3398954883077133822319581237472486629533832773658606240974980011352534575146593099441248529746198644134125073285288483505741834384822184028018785454859181 390 | dmp1 = 55430473883101152246097615323756881862950432952434504984590276578045386834041 391 | dmq1 = 41230473446336148758497170998210312513410109720579275453308960734626604833351 392 | iqmp = 84432856058147832764138703472538317942464795044718601494587194148378563942685 393 | p = 109910049826842557628963433845850622251367013324570378590557090526907918339059 394 | q = 106061213575088596820097699717773256317123615840075518129430834072505546216719 395 | 396 | # public key numbers 397 | e = 65537 398 | n = 11657193268733377953496174345085266431511790176736829620324311319483544845433376888008449023832068012445414318729055242605500539982129558003843075736527421 399 | 400 | public_numbers = rsa.RSAPublicNumbers(e, n) 401 | private_numbers = rsa.RSAPrivateNumbers(p, q, d, dmp1, dmq1, iqmp,public_numbers) 402 | private_key = default_backend().load_rsa_private_numbers(private_numbers) 403 | 404 | pubkey = public_numbers.public_key(default_backend()) 405 | 406 | puem = pubkey.public_bytes( 407 | encoding=serialization.Encoding.PEM, 408 | format=serialization.PublicFormat.SubjectPublicKeyInfo 409 | ) 410 | # 将PEM个数的数据写入文本文件中 411 | with open("pu_key.pem", 'w+') as f: 412 | f.writelines(puem.decode()) 413 | 414 | rpem = private_key.private_bytes(encoding=serialization.Encoding.PEM, 415 | format=serialization.PrivateFormat.TraditionalOpenSSL, 416 | encryption_algorithm=serialization.NoEncryption()) 417 | with open("pr_key.pem", 'w+') as f: 418 | f.writelines(rpem.decode()) 419 | 420 | return 421 | 422 | 423 | if __name__ == '__main__': 424 | gen_rsa_keypair() 425 | ``` 426 | 427 | ## 三.DES 428 | 429 | ### 1.简介 430 | 431 | `这是一个分组加密算法,解密和加密是同一个算法,可逆的` 432 | 433 | ### 2.DES加密与解密以及hex输出和bs64格式输出 434 | 435 | ```python 436 | import pyDes 437 | import base64 438 | 439 | Key = "12345678" #加密的key 440 | 441 | Iv = None #偏移量 442 | 443 | 444 | def bytesToHexString(bs): 445 | ''' 446 | bytes转16进制 447 | ''' 448 | return ''.join(['%02X ' % b for b in bs]) 449 | def hexStringTobytes(str): 450 | '''16进制转bytes''' 451 | str = str.replace(" ", "") 452 | return bytes.fromhex(str) 453 | 454 | # 加密 455 | def encrypt_str(data): 456 | # 加密方法 457 | #padmode填充方式 458 | #pyDes.ECB模式 459 | method = pyDes.des(Key, pyDes.ECB, Iv, pad=None, padmode=pyDes.PAD_PKCS5) 460 | # 执行加密码 hex输出 461 | k = method.encrypt(data) 462 | data = bytesToHexString(k).replace(' ','') 463 | #bs64手粗 464 | #data =base64.b64encode(k) 465 | return data 466 | 467 | # 解密 468 | def decrypt_str(data): 469 | method = pyDes.des(Key, pyDes.ECB, Iv, pad=None, padmode=pyDes.PAD_PKCS5) 470 | k =hexStringTobytes(data) 471 | #bs64 472 | #k = base64.b64decode(data) 473 | return method.decrypt(k) 474 | 475 | 476 | Encrypt = encrypt_str("aaa") 477 | print(Encrypt) 478 | Decrypt = decrypt_str(Encrypt) 479 | print(Decrypt) 480 | ``` 481 | 482 | ## 四.3des 483 | 484 | ### 代码模板 485 | 486 | ````python 487 | import hashlib, base64 488 | import json 489 | from cryptography.hazmat.primitives.padding import PKCS7 490 | from cryptography.hazmat.primitives.ciphers import algorithms 491 | from Crypto.Cipher import DES3 492 | import json 493 | 494 | def pkcs7padding(text): 495 | """ 496 | 明文使用PKCS7填充 497 | 最终调用DES3加密方法时,传入的是一个byte数组,要求是16的整数倍,因此需要对明文进行处理 498 | :param text: 待加密内容(明文) 499 | :return: 500 | """ 501 | bs = DES3.block_size # 16 502 | length = len(text) 503 | bytes_length = len(bytes(text, encoding='utf-8')) 504 | # tips:utf-8编码时,英文占1个byte,而中文占3个byte 505 | padding_size = length if (bytes_length == length) else bytes_length 506 | padding = bs - padding_size % bs 507 | # tips:chr(padding)看与其它语言的约定,有的会使用'\0' 508 | padding_text = chr(padding) * padding 509 | return text + padding_text 510 | 511 | 512 | def pkcs7_unpad(content): 513 | """ 514 | 解密时候用 515 | :param content: 516 | :return: 517 | """ 518 | if not isinstance(content, bytes): 519 | content = content.encode() 520 | pad = PKCS7(algorithms.DES3.block_size).unpadder() 521 | pad_content = pad.update(content) + pad.finalize() 522 | return pad_content 523 | 524 | 525 | def encrypt(key, content): 526 | """ 527 | DES3加密 528 | key,iv使用同一个 529 | 模式cbc 530 | 填充pkcs7 531 | :param key: 密钥 532 | :param content: 加密内容 533 | :return: 534 | """ 535 | key_bytes = bytes(key, encoding='utf-8') 536 | iv = key_bytes 537 | cipher = DES3.new(key_bytes, DES3.MODE_ECB) 538 | # 处理明文 539 | content_padding = pkcs7padding(content) 540 | # 加密 541 | encrypt_bytes = cipher.encrypt(bytes(content_padding, encoding='utf-8')) 542 | # 重新编码 543 | result = str(base64.b64encode(encrypt_bytes), encoding='utf-8') 544 | return result 545 | 546 | def decrypt(key,text): 547 | key_bytes = bytes(key, encoding='utf-8') 548 | iv = key_bytes 549 | cryptos = DES3.new(key_bytes, DES3.MODE_ECB) 550 | data = cryptos.decrypt(text) 551 | return json.loads(pkcs7_unpad(data)) 552 | ```` 553 | 554 | ## 五.AES加密 555 | 556 | ### 1.简介 557 | 558 | `和DES差不多,可逆的` 559 | 560 | ### 2.AES_ECB_pkcs5padding(该模板不兼容中文) 561 | 562 | ```python 563 | from Crypto.Cipher import AES 564 | import base64 565 | 566 | class Aes_ECB(object): 567 | def __init__(self): 568 | self.key = 'XXXXXXXXXXX' #秘钥 569 | self.MODE = AES.MODE_ECB 570 | self.BS = AES.block_size 571 | self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS) 572 | self.unpad = lambda s: s[0:-ord(s[-1])] 573 | 574 | # str不是16的倍数那就补足为16的倍数 575 | def add_to_16(value): 576 | while len(value) % 16 != 0: 577 | value += '\0' 578 | return str.encode(value) # 返回bytes 579 | 580 | def AES_encrypt(self, text): 581 | aes = AES.new(Aes_ECB.add_to_16(self.key), self.MODE) # 初始化加密器 582 | encrypted_text = str(base64.encodebytes(aes.encrypt(Aes_ECB.add_to_16(self.pad(text)))), 583 | encoding='utf-8').replace('\n', '') # 这个replace大家可以先不用,然后在调试出来的结果中看是否有'\n'换行符 584 | # 执行加密并转码返回bytes 585 | return encrypted_text 586 | ``` 587 | 588 | ### 3.AES_ECB_pkcs7padding(支持中文) 589 | 590 | ```python 591 | import hashlib, base64 592 | from Crypto.Cipher import AES 593 | from cryptography.hazmat.primitives.padding import PKCS7 594 | from cryptography.hazmat.primitives.ciphers import algorithms 595 | 596 | 597 | def pkcs7padding(text): 598 | """ 599 | 明文使用PKCS7填充 600 | 最终调用AES加密方法时,传入的是一个byte数组,要求是16的整数倍,因此需要对明文进行处理 601 | :param text: 待加密内容(明文) 602 | :return: 603 | """ 604 | bs = AES.block_size # 16 605 | length = len(text) 606 | bytes_length = len(bytes(text, encoding='utf-8')) 607 | # tips:utf-8编码时,英文占1个byte,而中文占3个byte 608 | padding_size = length if (bytes_length == length) else bytes_length 609 | padding = bs - padding_size % bs 610 | # tips:chr(padding)看与其它语言的约定,有的会使用'\0' 611 | padding_text = chr(padding) * padding 612 | return text + padding_text 613 | 614 | 615 | def pkcs7_unpad(content): 616 | """ 617 | 解密时候用 618 | :param content: 619 | :return: 620 | """ 621 | if not isinstance(content, bytes): 622 | content = content.encode() 623 | pad = PKCS7(algorithms.AES.block_size).unpadder() 624 | pad_content = pad.update(content) + pad.finalize() 625 | return pad_content 626 | 627 | 628 | def encrypt(key, content): 629 | """ 630 | AES加密 631 | key,iv使用同一个 632 | 模式cbc 633 | 填充pkcs7 634 | :param key: 密钥 635 | :param content: 加密内容 636 | :return: 637 | """ 638 | key_bytes = bytes(key, encoding='utf-8') 639 | iv = key_bytes 640 | cipher = AES.new(key_bytes, AES.MODE_ECB) 641 | # 处理明文 642 | content_padding = pkcs7padding(content) 643 | # 加密 644 | encrypt_bytes = cipher.encrypt(bytes(content_padding, encoding='utf-8')) 645 | # 重新编码 646 | result = str(base64.b64encode(encrypt_bytes), encoding='utf-8') 647 | return result 648 | 649 | def decrypt(key,text): 650 | key_bytes = bytes(key, encoding='utf-8') 651 | iv = key_bytes 652 | cryptos = AES.new(key_bytes, AES.MODE_ECB) 653 | data = cryptos.decrypt(text) 654 | return json.loads(pkcs7_unpad(data)) 655 | ``` 656 | 657 | ### 4.魔改的AES能解密,但是加密长度和js不同模板 658 | 659 | `可能是当中的中文影响的` 660 | 661 | ```python 662 | # _*_ coding: utf-8 _*_ 663 | import base64 664 | from cryptography.hazmat.primitives.padding import PKCS7 665 | from cryptography.hazmat.primitives.ciphers import algorithms 666 | import json 667 | import binascii 668 | from Crypto.Cipher import AES 669 | 670 | 671 | def pkcs7_pad(content): 672 | """ 673 | :param content: 674 | :return: 675 | """ 676 | if not isinstance(content, bytes): 677 | content = content.encode("raw_unicode_escape") 678 | pad = PKCS7(algorithms.AES.block_size).padder() 679 | pad_content = pad.update(content) + pad.finalize() 680 | print(pad_content) 681 | 682 | return pad_content 683 | 684 | 685 | def pkcs7_unpad(content): 686 | """ 687 | 解密时候用 688 | :param content: 689 | :return: 690 | """ 691 | if not isinstance(content, bytes): 692 | content = content.encode() 693 | pad = PKCS7(algorithms.AES.block_size).unpadder() 694 | pad_content = pad.update(content) + pad.finalize() 695 | return pad_content 696 | 697 | 698 | def encrypt_2(key, content, need_replace_wrod_list): 699 | """ 700 | AES加密 701 | key,iv使用同一个 702 | 模式cbc 703 | 填充pkcs7 704 | :param key: 密钥 705 | :param content: 加密内容 706 | :return: 707 | """ 708 | key_bytes = bytes(key, encoding='utf-8') 709 | cipher = AES.new(key_bytes, AES.MODE_ECB) 710 | # 处理明文 711 | print("need_replace_wrod_list:", need_replace_wrod_list) 712 | b = content.encode('utf-8') 713 | for word in need_replace_wrod_list: # str 714 | b = b.replace(word.encode("unicode_escape"), str_to_hex_x(word)) 715 | content_padding = pkcs7_pad(b) 716 | 717 | # 加密 718 | encrypt_bytes = cipher.encrypt(content_padding) 719 | # 重新编码 720 | result = str(base64.urlsafe_b64encode(encrypt_bytes), encoding="utf-8").replace("+", "-").replace("_", "/") 721 | return result 722 | 723 | 724 | def decrypt(key, text): 725 | text = base64.b64decode(text) 726 | key_bytes = bytes(key, encoding='utf-8') 727 | cryptos = AES.new(key_bytes, AES.MODE_ECB) 728 | data = cryptos.decrypt(text) 729 | print(data) 730 | return json.loads(pkcs7_unpad(data)) 731 | 732 | 733 | def dict_json(d): 734 | '''python字典转json字符串, 去掉一些空格''' 735 | j = json.dumps(d).replace('": ', '":').replace(', "', ',"').replace(", {", ",{") 736 | return j 737 | 738 | 739 | def str_to_hex(s): 740 | return r"/x" + r'/x'.join([hex(ord(c)).replace('0x', '') for c in s]) 741 | 742 | 743 | def str_to_hex_x(s): 744 | ''' 745 | 字符串转b'\xe7\xaf\xae\xe7\x90\x83' 746 | :param s: 747 | :return: 748 | ''' 749 | 750 | s = binascii.hexlify(s.encode()).decode() 751 | s_list = [] 752 | for index in range(2, len(s) + 2, 2): 753 | ss = f"x{s[index - 2:index]}" 754 | s_list.append(ss) 755 | 756 | s_1 = "\\".join(s_list) 757 | s_2 = f'b"\\{s_1}"' 758 | return eval(s_2) 759 | 760 | 761 | def get_chinese(string): 762 | """ 763 | 检查整个字符串是否包含中文 764 | :param string: 需要检查的字符串 765 | :return: bool 766 | """ 767 | s_list = [] 768 | s = "" 769 | for ch in string: 770 | if '\u4e00' <= ch <= '\u9fff': 771 | s += ch 772 | else: 773 | if s: 774 | s_list.append(s) 775 | s = "" 776 | 777 | return s_list 778 | 779 | 780 | if __name__ == '__main__': 781 | keyStr = "V2ZRDLQKR7IL1GZC" 782 | a = decrypt(keyStr, 783 | "Ui2PiLP14MUkvdXaxzqmTySxYtamuhHuwE5nwjxuwHH0IKJ3EVFr9gJODUuYlFl8RMaCZFQ7rW7Ye6S2YAkI6ARXWElx7zG8fAokxcgdH5UU7gpabvtgm3+2N9WF+g009NchttTUT8IIsoCX3tOiKdGQF48M5TMnbXTV9/cDUi4tp3ikDYuS9k8nU/iSoepJZ0Gd3xt27IA8wNGR1n7oDd3rEKitOOY3CEgNxBm/MviMnqYZtmWA4G7NlXFGZqT5I8HqPfsUub5vCYclx5z1Zru1ay5sQ5a2vYhpGqYJcLk0OZCgM/qlZmfVGhFrkWLGOnjWlqal7U9z4bVKP8X8lc2uA0dUisxczdaKqKNQ0P66ByVzTEmNiNIOBgvIcZ3KnQrNK5nqna4OdjrygczbPKuartSsmgM503GnLAwXtMshewdukQstasl8ZR/XOsR+wCX4MKOmrZoOyklgSay6LIUv4D29TTUEzT1SMTl7yKM4cwgpBcS2UwXsvWKGNZxGoYxqqEdBj6+DxzLafXSdyfh38KAQekvpOwNAHOfo4r54Ep1Bln+5CDehGiBTqVW2") 784 | print(a) 785 | t = {'venTypeId': '8dc0e52c-564a-4d9a-9cb2-08477f1a18d4', 'venueId': '3b10ff47-7e83-4c21-816c-5edc257168c1', 786 | 'fieldType': '篮球', 'returnUrl': 'https://sports.sjtu.edu.cn/#/paymentResult/1', 'scheduleDate': '2022-02-23', 787 | 'week': '3', 'spaces': [ 788 | {'venuePrice': '15', 'count': 1, 'status': 1, 'scheduleTime': '12:00-13:00', 'subSitename': '场地1-2', 789 | 'subSiteId': '391cff6c-b950-453b-ae80-7a1afa6ac7f1', 'tensity': '1', 'venueNum': 1}], 'tenSity': '紧张'} 790 | t_1 = str(t) 791 | print(str_to_hex_x("篮球")) 792 | t = json.dumps(t, separators=(',', ':')) 793 | need_replace_wrod_list = get_chinese(t_1) 794 | print(encrypt_2(keyStr, t, need_replace_wrod_list)) 795 | print( 796 | "Ui2PiLP14MUkvdXaxzqmTySxYtamuhHuwE5nwjxuwHH0IKJ3EVFr9gJODUuYlFl8RMaCZFQ7rW7Ye6S2YAkI6ARXWElx7zG8fAokxcgdH5UU7gpabvtgm3+2N9WF+g009NchttTUT8IIsoCX3tOiKdGQF48M5TMnbXTV9/cDUi4tp3ikDYuS9k8nU/iSoepJZ0Gd3xt27IA8wNGR1n7oDd3rEKitOOY3CEgNxBm/MviMnqYZtmWA4G7NlXFGZqT5I8HqPfsUub5vCYclx5z1Zru1ay5sQ5a2vYhpGqYJcLk0OZCgM/qlZmfVGhFrkWLGOnjWlqal7U9z4bVKP8X8lc2uA0dUisxczdaKqKNQ0P66ByVzTEmNiNIOBgvIcZ3KnQrNK5nqna4OdjrygczbPKuartSsmgM503GnLAwXtMshewdukQstasl8ZR/XOsR+wCX4MKOmrZoOyklgSay6LIUv4D29TTUEzT1SMTl7yKM4cwgpBcS2UwXsvWKGNZxGoYxqqEdBj6+DxzLafXSdyfh38KAQekvpOwNAHOfo4r54Ep1Bln+5CDehGiBTqVW2") 797 | 798 | ``` 799 | 800 | ### 5.识别是AES_128\192\256怎么识别 801 | 802 | ````python 803 | 根据key的长度进行识别 804 | 128 16位 805 | 192 24位 806 | 256 32位 807 | #基本上不足的部分都是以0进行填充 808 | ```` 809 | 810 | ### 6.ECB和CBC在代码实现上的区别 811 | 812 | ```python 813 | CBC相比ECB多一个偏移量,至于其他地方代码区别不大 814 | ``` 815 | 816 | ### 7.gzip输出解密 817 | 818 | ```python 819 | # -*- coding: utf-8 -*- 820 | from cryptography.hazmat.primitives.ciphers import algorithms 821 | from cryptography.hazmat.primitives.ciphers import Cipher 822 | from cryptography.hazmat.primitives.ciphers import modes 823 | from cryptography.hazmat.backends import default_backend 824 | 825 | class AES_GZIP: 826 | @staticmethod 827 | def gzip_decode(content): 828 | buf = io.BytesIO(content) 829 | gf = gzip.GzipFile(fileobj=buf) 830 | content = gf.read() 831 | return content 832 | 833 | def pwd_decrypt(self, content): 834 | key = b'XXXX' 835 | iv = b'XXXXX' 836 | cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) 837 | decryptor = cipher.decryptor() 838 | data = decryptor.update(content) 839 | return self.gzip_decode(data) 840 | ``` 841 | 842 | ## 六.SM2/SM4 843 | 844 | ### GMSSL模块介绍 845 | 846 | GmSSL是一个开源的加密包的python实现,支持SM2/SM3/SM4等国密(国家商用密码)算法、项目采用对商业应用友好的类BSD开源许可证,开源且可以用于闭源的商业应用。 847 | 848 | ### 安装模块 849 | 850 | ``` 851 | pip install gmssl 852 | #https://github.com/duanhongyi/gmssl/blob/master/README.md官方文档 853 | ``` 854 | 855 | ### SM2算法 856 | 857 | RSA算法的危机在于其存在亚指数算法,对ECC算法而言一般没有亚指数攻击算法 SM2椭圆曲线公钥密码算法:我国自主知识产权的商用密码算法,是ECC(Elliptic Curve Cryptosystem)算法的一种,基于椭圆曲线离散对数问题,计算复杂度是指数级,求解难度较大,同等安全程度要求下,椭圆曲线密码较其他公钥算法所需密钥长度小很多。 858 | 859 | gmssl是包含国密SM2算法的Python实现, 提供了 `encrypt`、 `decrypt`等函数用于加密解密, 用法如下: 860 | 861 | #### 1. 初始化`CryptSM2` 862 | 863 | ``` 864 | import base64 865 | import binascii 866 | from gmssl import sm2, func 867 | #16进制的公钥和私钥 868 | private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5' 869 | public_key = 'B9C9A6E04E9C91F7BA880429273747D7EF5DDEB0BB2FF6317EB00BEF331A83081A6994B8993F3F5D6EADDDB81872266C87C018FB4162F5AF347B483E24620207' 870 | sm2_crypt = sm2.CryptSM2( 871 | public_key=public_key, private_key=private_key) 872 | ``` 873 | 874 | #### 2. `encrypt`和`decrypt` 875 | 876 | ``` 877 | #数据和加密后数据为bytes类型 878 | data = b"111" 879 | enc_data = sm2_crypt.encrypt(data) 880 | dec_data =sm2_crypt.decrypt(enc_data) 881 | assert dec_data == data 882 | ``` 883 | 884 | #### 3.`sign`和`verify` 885 | 886 | ``` 887 | data = b"111" # bytes类型 888 | random_hex_str = func.random_hex(sm2_crypt.para_len) 889 | sign = sm2_crypt.sign(data, random_hex_str) # 16进制 890 | assert sm2_crypt.verify(sign, data) # 16进制 891 | ``` 892 | 893 | ### SM4算法 894 | 895 | 国密SM4(无线局域网SMS4)算法, 一个分组算法, 分组长度为128bit, 密钥长度为128bit, 算法具体内容参照[SM4算法](https://drive.google.com/file/d/0B0o25hRlUdXcbzdjT0hrYkkwUjg/view?usp=sharing)。 896 | 897 | gmssl是包含国密SM4算法的Python实现, 提供了 `encrypt_ecb`、 `decrypt_ecb`、 `encrypt_cbc`、 `decrypt_cbc`等函数用于加密解密, 用法如下: 898 | 899 | #### 1. 初始化`CryptSM4` 900 | 901 | ``` 902 | from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT 903 | 904 | key = b'3l5butlj26hvv313' 905 | value = b'111' # bytes类型 906 | iv = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' # bytes类型 907 | crypt_sm4 = CryptSM4() 908 | ``` 909 | 910 | #### 2. `encrypt_ecb`和`decrypt_ecb` 911 | 912 | ``` 913 | crypt_sm4.set_key(key, SM4_ENCRYPT) 914 | encrypt_value = crypt_sm4.crypt_ecb(value) # bytes类型 915 | crypt_sm4.set_key(key, SM4_DECRYPT) 916 | decrypt_value = crypt_sm4.crypt_ecb(encrypt_value) # bytes类型 917 | assert value == decrypt_value 918 | ``` 919 | 920 | #### 3. `encrypt_cbc`和`decrypt_cbc` 921 | 922 | ``` 923 | crypt_sm4.set_key(key, SM4_ENCRYPT) 924 | encrypt_value = crypt_sm4.crypt_cbc(iv , value) # bytes类型 925 | crypt_sm4.set_key(key, SM4_DECRYPT) 926 | decrypt_value = crypt_sm4.crypt_cbc(iv , encrypt_value) # bytes类型 927 | assert value == decrypt_value 928 | ``` 929 | 930 | ## 七.其他不怎么需要模板的加密 931 | 932 | ### 1.base64加密 933 | 934 | ```python 935 | import base64 #base64也是用来加密的,但是这个是可以解密的 936 | s = "password" 937 | print(base64.b64encode(s.encode()) ) #加密 938 | ``` 939 | 940 | ### 2.uuid 941 | 942 | ```python 943 | #有时候你会看到一些比如xxxx-xxxx-xxx-xxx误以为是加密其实很多是uuid模块自动生成的 944 | 随机数格式为:xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx 945 | 946 | python的uuid模块提供UUID类和函数uuid1(), uuid3(), uuid4(), uuid5() 947 | 948 | 1.uuid.uuid1([node[, clock_seq]]) 949 | 基于时间戳 950 | 951 | 使用主机ID, 序列号, 和当前时间来生成UUID, 可保证全球范围的唯一性. 但由于使用该方法生成的UUID中包含有主机的网络地址, 因此可能危及隐私. 该函数有两个参数, 如果 node 参数未指定, 系统将会自动调用 getnode() 函数来获取主机的硬件地址. 如果 clock_seq 参数未指定系统会使用一个随机产生的14位序列号来代替. 952 | 953 | 2.uuid.uuid3(namespace, name) 954 | 基于名字的MD5散列值 955 | 956 | 通过计算命名空间和名字的MD5散列值来生成UUID, 可以保证同一命名空间中不同名字的唯一性和不同命名空间的唯一性, 但同一命名空间的同一名字生成的UUID相同. 957 | 958 | 3.uuid.uuid4() 959 | 基于随机数 960 | 961 | 通过随机数来生成UUID. 使用的是伪随机数有一定的重复概率. 962 | 963 | 4.uuid.uuid5(namespace, name) 964 | 基于名字的SHA-1散列值 965 | ``` 966 | 967 | ### 3.md5加盐 968 | 969 | ```python 970 | import hashlib 971 | 972 | #注意加密顺序 973 | m=hashlib.md5('加密内容'.encode('utf8')) 974 | m.update(b"盐") 975 | sign = m.hexdigest() 976 | ``` 977 | 978 | ### 4.字符串和16进制字符串之间转换 979 | 980 | ```python 981 | import binascii 982 | 983 | binascii.b2a_hex('字符串'.encode()) 输出b'e5ad97e7aca6e4b8b2' 984 | binascii.a2b_hex('e5ad97e7aca6e4b8b2').decode() 输出 '字符串' 985 | 986 | 987 | def str_to_hex_x(s): #输入篮球,输出 988 | ''' 989 | 字符串转b'\xe7\xaf\xae\xe7\x90\x83' 990 | :param s: 991 | :return: 992 | ''' 993 | 994 | s = binascii.hexlify(s.encode()).decode() 995 | s_list = [] 996 | for index in range(2,len(s)+2,2): 997 | ss = f"x{s[index-2:index]}" 998 | s_list.append(ss) 999 | 1000 | s_1 = "\\".join(s_list) 1001 | s_2 = f'b"\\{s_1}"' 1002 | return eval(s_2) 1003 | 1004 | ``` 1005 | 1006 | 1007 | 1008 | ### 5.HmacSHA256加密算法 1009 | 1010 | ```python 1011 | from hashlib import sha256 1012 | import hmac 1013 | 1014 | def get_sign(data, key): 1015 | key = key.encode('utf-8') 1016 | message = data.encode('utf-8') 1017 | sign = base64.b64encode(hmac.new(key, message, digestmod=sha256).digest()) 1018 | sign = str(sign, 'utf-8') 1019 | print(sign) 1020 | return sign 1021 | ``` 1022 | 1023 | ## 6.字节数组转字符串 1024 | 1025 | ```python 1026 | a = bytearray(l2) 1027 | b = a.decode('utf8') 1028 | print(b) 1029 | ``` 1030 | 1031 | ## 7.java字节数组转python字节数组 1032 | 1033 | ```python 1034 | def jb2pb(byte_arr): 1035 | 1036 | """ 1037 | java 字节数组转python字节数组 1038 | :return: 1039 | """ 1040 | 1041 | return [i + 256 if i < 0 else i for i in byte_arr] 1042 | ``` 1043 | --------------------------------------------------------------------------------