Python使用Crypto庫實現(xiàn)加密解密的示例詳解
一:crypto庫安裝
pycrypto,pycryptodome是crypto第三方庫,pycrypto已經(jīng)停止更新三年了,所以不建議安裝這個庫;pycryptodome是pycrypto的延伸版本,用法和pycrypto 是一模一樣的;所以只需要安裝pycryptodome就可以了
pip install pycryptodome
二:python使用crypto
1:crypto的加密解密組件des.py
#!/usr/bin/env python # -*- coding: utf-8 -*- from Crypto.Cipher import DES from binascii import b2a_hex, a2b_hex class MyDESCrypt: #自己實現(xiàn)的DES加密類 def __init__(self, key = ''): #密鑰長度必須為64位,也就是8個字節(jié) if key is not '': self.key = key.encode('utf-8') else: self.key = '12345678'.encode('utf-8') self.mode = DES.MODE_CBC # 加密函數(shù),如果text不足16位就用空格補(bǔ)足為16位, # 如果大于16當(dāng)時不是16的倍數(shù),那就補(bǔ)足為16的倍數(shù)。 def encrypt(self,text): try: text = text.encode('utf-8') cryptor = DES.new(self.key, self.mode, self.key) # 這里密鑰key 長度必須為16(DES-128), # 24(DES-192),或者32 (DES-256)Bytes 長度 # 目前DES-128 足夠目前使用 length = 16 #lenth可以設(shè)置為8的倍數(shù) count = len(text) if count < length: add = (length - count) # \0 backspace # text = text + ('\0' * add) text = text + ('\0' * add).encode('utf-8') elif count > length: add = (length - (count % length)) # text = text + ('\0' * add) text = text + ('\0' * add).encode('utf-8') self.ciphertext = cryptor.encrypt(text) # 因為DES加密時候得到的字符串不一定是ascii字符集的,輸出到終端或者保存時候可能存在問題 # 所以這里統(tǒng)一把加密后的字符串轉(zhuǎn)化為16進(jìn)制字符串 return b2a_hex(self.ciphertext) except: return "" # 解密后,去掉補(bǔ)足的空格用strip() 去掉 def decrypt(self, text): try: cryptor = DES.new(self.key, self.mode, self.key) plain_text = cryptor.decrypt(a2b_hex(text)) # return plain_text.rstrip('\0') return bytes.decode(plain_text).rstrip('\0') except: return ""
2:crypto組件使用
from . import des msg = "password is 961223" key = "12345678" #key值可傳可不傳 des1 = des.MyDESCrypt() #加密 cipherTxt = des1.encrypt(msg) #返回值為bytes型 print(cipherTxt) #解密 decTxt = des1.decrypt(cipherTxt); #返回值為str型 print(decTxt)
知識補(bǔ)充
下面是小編為大家整理的一些Python利用pycrypto進(jìn)行加密解密的示例,希望對大家有所幫助
AES-ECB加解密
下面是采用 ECB
并以pkcs7
填充的加密與解密方法
import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad def aes_encrypt(secret_key, data): """加密數(shù)據(jù) :param secret_key: 加密秘鑰 :param data: 需要加密數(shù)據(jù) """ data = bytes(data, encoding="utf-8") # 填充數(shù)據(jù)采用pkcs7 data = pad(data, block_size=16, style="pkcs7") # 創(chuàng)建加密器 cipher = AES.new(key=secret_key.encode("utf-8"), mode=AES.MODE_ECB) # 對數(shù)據(jù)進(jìn)行加密 encrypted_data = cipher.encrypt(data) # 對數(shù)據(jù)進(jìn)行base64編碼 encrypted_data = base64.b64encode(encrypted_data) return encrypted_data.decode() def aes_decrypt(secret_key, data): """解密數(shù)據(jù) """ 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("原始數(shù)據(jù):%s" % data) r = aes_encrypt(key, data) print("加密數(shù)據(jù):%s" % r) r = aes_decrypt("22a1d4c4263e83d7f8c33a321eb19ae7", r) print("解密數(shù)據(jù):%s" % r)
執(zhí)行結(jié)果如下
AES-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: 附加數(shù)據(jù),一般為None :param nonce: 隨機(jī)值,和MD5的“加鹽”有些類似,目的是防止同樣的明文塊,始終加密成同樣的密文塊 :return: """ key = key.encode('utf-8') data = data.encode('utf-8') # 假如先后端約定隨機(jī)值為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()) # 加密數(shù)據(jù) cipher_data, auth_tag = cipher.encrypt_and_digest(data) # 拼接數(shù)據(jù) join_data = nonce + cipher_data + auth_tag # 拼接數(shù)據(jù)為:前16位為nonce,后16位為驗簽值 # 返回base64編碼數(shù)據(jù) 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 方法返回的數(shù)據(jù) :return: """ key = key.encode('utf-8') # 進(jìn)行base64解碼 debase64_cipher_data = base64.b64decode(cipher_data) # 分割數(shù)據(jù) 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()) # 解密數(shù)據(jù) 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("原始數(shù)據(jù):" + data) cipher_data = encrypt_aes_gcm(aes_key, data, associated_data=associated_data, nonce=nonce) print("加密數(shù)據(jù):" + cipher_data) de_data = decrypt_aes_gcm(aes_key, cipher_data, associated_data) print("解密數(shù)據(jù):" + de_data)
執(zhí)行結(jié)果如下:
使用RAS實現(xiàn)非對稱加解密
# -*- 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) # 加密數(shù)據(jù)。注意,在python3中加密的數(shù)據(jù)必須是bytes類型的數(shù)據(jù),不能是str類型的數(shù)據(jù) encrypt_data = cipher.encrypt(data.encode(encoding="utf-8")) # # 對數(shù)據(jù)進(jìn)行base64編碼 encrypt_data = base64.b64encode(encrypt_data) # 公鑰每次加密的結(jié)果不一樣。原因是每次padding的數(shù)據(jù)不一樣 return encrypt_data.decode() def rsa_decrypt(cipher_data, private_key): """私鑰解密""" # 加載私鑰 rsakey = RSA.importKey(private_key) # 生成密碼器 cipher = PKCS1_v1_5.new(rsakey) # 將密文解密成明文,返回的是一個bytes類型數(shù)據(jù),需要自己轉(zhuǎn)換成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)
執(zhí)行結(jié)果如下
到此這篇關(guān)于Python使用Crypto庫實現(xiàn)加密解密的示例詳解的文章就介紹到這了,更多相關(guān)Python Crypto加密解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
由Python運算π的值深入Python中科學(xué)計算的實現(xiàn)
這篇文章主要介紹了由Python運算π的值深入Python中科學(xué)計算的實現(xiàn),由簡單的計算發(fā)散出各種算法的講解,需要的朋友可以參考下2015-04-04

Python利用正則表達(dá)式匹配并截取指定子串及去重的方法

Python和C語言利用棧分別實現(xiàn)進(jìn)制轉(zhuǎn)換

tensorflow 環(huán)境變量設(shè)置方式

Python根據(jù)當(dāng)前日期取去年同星期日期