Python使用Crypto庫(kù)實(shí)現(xiàn)加密解密的示例詳解
一:crypto庫(kù)安裝
pycrypto,pycryptodome是crypto第三方庫(kù),pycrypto已經(jīng)停止更新三年了,所以不建議安裝這個(gè)庫(kù);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: #自己實(shí)現(xiàn)的DES加密類
def __init__(self, key = ''):
#密鑰長(zhǎng)度必須為64位,也就是8個(gè)字節(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)時(shí)不是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 長(zhǎng)度必須為16(DES-128),
# 24(DES-192),或者32 (DES-256)Bytes 長(zhǎng)度
# 目前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)
# 因?yàn)镈ES加密時(shí)候得到的字符串不一定是ascii字符集的,輸出到終端或者保存時(shí)候可能存在問(wèn)題
# 所以這里統(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)
知識(shí)補(bǔ)充
下面是小編為大家整理的一些Python利用pycrypto進(jìn)行加密解密的示例,希望對(duì)大家有所幫助
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)
# 對(duì)數(shù)據(jù)進(jìn)行加密
encrypted_data = cipher.encrypt(data)
# 對(duì)數(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字符長(zhǎng)度的字符串
: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位長(zhǎng)度的字符串
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位為驗(yàn)簽值
# 返回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實(shí)現(xiàn)非對(duì)稱加解密
# -*- 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算法實(shí)例
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"))
# # 對(duì)數(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)
# 將密文解密成明文,返回的是一個(gè)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庫(kù)實(shí)現(xiàn)加密解密的示例詳解的文章就介紹到這了,更多相關(guān)Python Crypto加密解密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
由Python運(yùn)算π的值深入Python中科學(xué)計(jì)算的實(shí)現(xiàn)
這篇文章主要介紹了由Python運(yùn)算π的值深入Python中科學(xué)計(jì)算的實(shí)現(xiàn),由簡(jiǎn)單的計(jì)算發(fā)散出各種算法的講解,需要的朋友可以參考下2015-04-04
python實(shí)現(xiàn)簡(jiǎn)易數(shù)碼時(shí)鐘
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡(jiǎn)易數(shù)碼時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Python+Pygame實(shí)現(xiàn)彩色五子棋游戲
這篇文章主要為大家詳細(xì)介紹了如何溧陽(yáng)Python和Pygame實(shí)現(xiàn)彩色五子棋游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-02-02
Python利用正則表達(dá)式匹配并截取指定子串及去重的方法
Python和C語(yǔ)言利用棧分別實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換
tensorflow 環(huán)境變量設(shè)置方式
Python根據(jù)當(dāng)前日期取去年同星期日期

