本人在java中運(yùn)行的一段AES加密代碼姚建,采用的是GCM加密模式坦报,出于某種原因需要將這部分代碼移植到python項(xiàng)目中去,但發(fā)現(xiàn)python自帶的加密庫(kù)中不支持GCM這一加密模式撑帖,經(jīng)過(guò)google之后铐炫,發(fā)現(xiàn)第三方加密庫(kù)pyca/cryptography支持,所以記錄下來(lái)
一习柠、GCM加密模式的介紹
GCM中的G就是指GMAC匀谣,C就是指CTR。
GCM可以提供對(duì)消息的加密和完整性校驗(yàn)资溃,另外武翎,它還可以提供附加消息的完整性校驗(yàn)。在實(shí)際應(yīng)用場(chǎng)景中溶锭,有些信息是我們不需要保密宝恶,但信息的接收者需要確認(rèn)它的真實(shí)性的,例如源IP趴捅,源端口垫毙,目的IP,IV拱绑,等等综芥。因此,我們可以將這一部分作為附加消息加入到MAC值的計(jì)算當(dāng)中猎拨。下圖的Ek表示用對(duì)稱秘鑰k對(duì)輸入做AES運(yùn)算膀藐。最后,密文接收者會(huì)收到密文红省、IV(計(jì)數(shù)器CTR的初始值)额各、MAC值。
(以上介紹原文鏈接:https://blog.csdn.net/T0mato_/article/details/53160772)
之所以選用GCM吧恃,也就是因?yàn)樗瘸S玫腃BC加密模式更加安全和完善虾啦,以后建議同學(xué)們新開發(fā)的軟件可以考慮采用這種方式
二、Python(3)實(shí)現(xiàn)
1痕寓、安裝cryptography
pip install cryptography
2缸逃、代碼實(shí)現(xiàn)
import os
from cryptography.hazmat.backendsimport default_backend
from cryptography.hazmat.primitives.ciphersimport (
Cipher, algorithms, modes
)
def encrypt(key, plaintext):
iv = os.urandom(12)
encryptor = Cipher(
algorithms.AES(key),
modes.GCM(iv),
backend=default_backend()
).encryptor()
ciphertext = encryptor.update(plaintext) + encryptor.finalize() + encryptor.tag #將tag直接追加在最后,即可和java解密代碼兼容
return ciphertext.hex().upper()
if __name__ =='__main__':
key = os.urandom(32)
ciphertext = encrypt(key, b"a secret message!")
print(ciphertext)
以上代碼僅作參考厂抽,更多詳細(xì)內(nèi)容可移至此處學(xué)習(xí):https://cryptography.io/en/latest/hazmat/primitives/symmetric-encryption/#cryptography.hazmat.primitives.ciphers.modes.GCM