Python_pycrypto_加密解密(推荐)
1、安装
在 Windows环境安装 pycryptodome 模块 pip install pycryptodome
在 Linux环境安装 pycrypto模块 pip install pycrypto
2、AES对称加密
2.1 ECB模式
下面是采用 ECB
并以pkcs7
填充的加密与解密方法
import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad def aes_encrypt(secret_key, data): """加密数据 :param secret_key: 加密秘钥 :param data: 需要加密数据 """ data = bytes(data, encoding="utf-8") # 填充数据采用pkcs7 data = pad(data, block_size=16, style="pkcs7") # 创建加密器 cipher = AES.new(key=secret_key.encode("utf-8"), mode=AES.MODE_ECB) # 对数据进行加密 encrypted_data = cipher.encrypt(data) # 对数据进行base64编码 encrypted_data = base64.b64encode(encrypted_data) return encrypted_data.decode() def aes_decrypt(secret_key, data): """解密数据 """ data = base64.b64decode(data) cipher = AES.new(key=secret_key.encode("utf-8"), mode=AES.MODE_ECB) decrypt_data = cipher.decrypt(data) decrypt_data = unpad(decrypt_data, 16, style="pkcs7") return decrypt_data.decode("utf-8") if __name__ == '__main__': key = "22a1d4c4263e83d7f8c33a321eb19ae7" data = "asdASD73j8H9k6C1asvhBOK0PXOzJM7dsqXysssW" print("原始数据:%s" % data) r = aes_encrypt(key, data) print("加密数据:%s" % r) r = aes_decrypt(key, r) print("解密数据:%s" % r)
执行结果如下
2.2 GCM模式
import base64 import random import string from Crypto.Cipher import AES def encrypt_aes_gcm(key, data, associated_data=None, nonce=None): """ AES-GCM加密 :param key: 密钥。16, 24 or 32字符长度的字符串 :param data: 待加密字符串 :param associated_data: 附加数据,一般为None :param nonce: 随机值,和MD5的“加盐”有些类似,目的是防止同样的明文块,始终加密成同样的密文块 :return: """ key = key.encode('utf-8') data = data.encode('utf-8') # 假如先后端约定随机值为16位长度的字符串 nonce = nonce or "1234567812345678" nonce = nonce.encode("utf-8") # 生成加密器 cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) if associated_data is not None: cipher.update(associated_data.encode()) # 加密数据 cipher_data, auth_tag = cipher.encrypt_and_digest(data) # 拼接数据 join_data = nonce + cipher_data + auth_tag # 拼接数据为:前16位为nonce,后16位为验签值 # 返回base64编码数据 return base64.b64encode(join_data).decode('utf-8') def decrypt_aes_gcm(key, cipher_data, associated_data=None): """ AES-GCM解密 :param cipher_data: encrypt_aes_gcm 方法返回的数据 :return: """ key = key.encode('utf-8') # 进行base64解码 debase64_cipher_data = base64.b64decode(cipher_data) # 分割数据 nonce = debase64_cipher_data[:16] cipher_data = debase64_cipher_data[16:-16] auth_tag = debase64_cipher_data[-16:] cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) if associated_data is not None: cipher.update(associated_data.encode()) # 解密数据 plaintext = cipher.decrypt_and_verify(cipher_data, auth_tag) return plaintext.decode() if __name__ == '__main__': aes_key = 'DnKRYZbvVzdhPlF10rtcxmi5Cj36AbCd' associated_data = "1234567812345678" nonce = ''.join(random.sample(string.ascii_letters + string.digits, 16)) data = '{"lang":"zh-CN","pageNumber":1,"pageSize":10,"cycleId":"1522973936269266945"}' print("原始数据:" + data) cipher_data = encrypt_aes_gcm(aes_key, data, associated_data=associated_data, nonce=nonce) print("加密数据:" + cipher_data) de_data = decrypt_aes_gcm(aes_key, cipher_data, associated_data) print("解密数据:" + de_data)
执行结果如下:
2.3 CBC模式
import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad def aes_encrypt(aes_key, iv, data): """加密数据 :param aes_key: 加密秘钥 :param data: 需要加密数据 :param iv: 加解密初始化矢量,长度必须为16 bytes """ data = bytes(data, encoding="utf-8") # 填充数据采用pkcs7 data = pad(data, block_size=16, style="pkcs7") # 创建加密器 cipher = AES.new(key=aes_key.encode("utf-8"), mode=AES.MODE_CBC, iv=iv.encode("utf-8")) # 对数据进行加密 encrypted_data = cipher.encrypt(data) # print(encrypted_data) # 对数据进行base64编码 encrypted_data = base64.b64encode(encrypted_data) return encrypted_data.decode() def aes_decrypt(aes_key, iv, data): """解密数据 """ data = base64.b64decode(data) cipher = AES.new(key=aes_key.encode("utf-8"), mode=AES.MODE_CBC, iv=iv.encode("utf-8")) decrypt_data = cipher.decrypt(data) decrypt_data = unpad(decrypt_data, 16, style="pkcs7") return decrypt_data.decode("utf-8") aes_key = "7uYhf14h094&fe12" iv = "8AYhf14h094ES434" data = "hello python!" encrypted_data = aes_encrypt(aes_key, iv, data) print(encrypted_data) print(aes_decrypt(aes_key, iv, encrypted_data))
三、RSA非对称加密
使用RAS实现非对称加解密
# -*- coding: utf-8 -*- from Crypto import Random from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 import base64 def get_key(): """生成公私钥""" # 生成rsa算法实例 rsa = RSA.generate(1024, Random.new().read) # 生成公钥私钥 private_pem = rsa.exportKey() public_pem = rsa.publickey().exportKey() return { "public_key": public_pem.decode(), "private_key": private_pem.decode() } def rsa_encrypt(data, public_key): """公钥加密""" # 加载公钥 rsakey = RSA.importKey(public_key) # 生成密码器 cipher = PKCS1_v1_5.new(rsakey) # 加密数据。注意,在python3中加密的数据必须是bytes类型的数据,不能是str类型的数据 encrypt_data = cipher.encrypt(data.encode(encoding="utf-8")) # # 对数据进行base64编码 encrypt_data = base64.b64encode(encrypt_data) # 公钥每次加密的结果不一样。原因是每次padding的数据不一样 return encrypt_data.decode() def rsa_decrypt(cipher_data, private_key): """私钥解密""" # 加载私钥 rsakey = RSA.importKey(private_key) # 生成密码器 cipher = PKCS1_v1_5.new(rsakey) # 将密文解密成明文,返回的是一个bytes类型数据,需要自己转换成str decrypt_data = cipher.decrypt(base64.b64decode(cipher_data), "解密失败") return decrypt_data.decode() if __name__ == '__main__': # k = get_key() # public_key = k.get("public_key") # private_key = k.get("private_key") # # print(public_key) # print(private_key) public_key = """-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKF7UTc5K61xMUKrCtld0dYJf/ KjT5P+R3H8n8my8aEYqUaWQjO3CkQGsLN//5Tbs8g5Of4vAkqytoleWxSQxFGO7T YuOQ7UtvRhKqTKvX8PvDnKX7ebKzw3zIXt1QDRbc2bJTqVAbPDdT1DNvyocQdCMC BtPA2algMRs4Zq0qpwIDAQAB -----END PUBLIC KEY----- """ private_key = """-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQDKF7UTc5K61xMUKrCtld0dYJf/KjT5P+R3H8n8my8aEYqUaWQj O3CkQGsLN//5Tbs8g5Of4vAkqytoleWxSQxFGO7TYuOQ7UtvRhKqTKvX8PvDnKX7 ebKzw3zIXt1QDRbc2bJTqVAbPDdT1DNvyocQdCMCBtPA2algMRs4Zq0qpwIDAQAB AoGAE3LSn0uZDFgUYvV0yU/J1sDr/8dtD6uhbgFmK+Q3VTfo8T1vQKDAx13Xr121 SaW8Zid3doSdfbnnVIpQb45LGtM5GLLDEslSBVJ/u2pNaUF/JmwK+PZVe02g2zCX rtmceROdOQZo66Iq3jlV3PWcuZdTr1n6XLgbXNyMyeQHf7ECQQDNfJN/ifeXZIk6 ouqWMGdlW6kFTCHXBGeSETqG5otfJWyvGDPOpN+950VXEObcU5y+yyGMX9CEyMNX B65U/nY5AkEA+8WLBoz2orSptQTB8aDsBfy7rzOnqC7cPepSzsu5oIkNxe1ZJC3j p0m/0UYpKOgb6RWGi4MhtdfYubMpRQ2n3wJACPoLO4Qcc9mpgQ1C8EK3EZ96d8fG pq0DlUb5ZpFFv2dUIyYMhVeAirxCtDYBz9g7Pb6D/azl4BchKXklbYMcSQJAViwr xGc090V8nG9vbiNVBUuWdYXpiV/Yk/yCsTL7at3d7/OnwgFO3PAaDifEaLLg8qsi bNfKDvI8xHp00qS04wJAeNJg/6C4Xwo1GYeAg2HIy0yHIQ9gs1hwA5zXdUc/7t+9 UkZj7rd2ySQJmXsO2LU0/SvmLIjiNoG3frjWS+dqLA== -----END RSA PRIVATE KEY----- """ data = "hello python!" cipher_data = rsa_encrypt(data, public_key) print(cipher_data) decrypt_data = rsa_decrypt(cipher_data, private_key) print(decrypt_data)
执行结果如下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通