首页 > 编程语言 > 详细

Python Crypto AES加密模式踩坑记

时间:2021-03-07 15:28:51      阅读:362      评论:0      收藏:0      [点我收藏+]

前言

  demo code使用的lib 版本为 :pycryptodome 3.10.1
  写了一小段AES加密的demo code, 运行起来错误不断,花费了半天时间逐一解决。分享出来,希望能对大家有所帮助!
  同时,关于AES 加密模式的说明可以参考这篇文章,讲的很清晰:https://blog.csdn.net/slslslyxz/article/details/111232040

 

问题一:decrypt() cannot be called after encrypt()

  运行时报告:Exception has occurred: TypeError, decrypt() cannot be called after encrypt()
  出现这个问题的原因,在encrypt / decrypt函数中有说明,由于encrypt / decrypt是stateful,不能用加密的对象再去解蜜; 
  A cipher object is stateful: once you have encrypted a message , you cannot encrypt (or decrypt) another message using the same object. 

  解决方法就是重新new一个对象用来处理解密

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad

key=b1234567890123456cipher=AES.new(key,AES.MODE_CBC)

text=bsecret text
padtext=pad(text,16,style=pkcs7)
cipherText=cipher.encrypt(padtext)
print(padtext)
print(cipherText)

plaintext=cipher.decrypt(cipherText)  #can‘t use same object to decrypt
print(plaintext)

 

 问题二:Data must be padded to 16 byte boundary in CBC mode

  这个是AES加密算法模式导致的。 AES只能以Block的模式加密, 且Block大小为16Byte.  加密的key大小为:16,24,32,对应到128bit, 192bit, 256bit加密

  # Size of a data block (in bytes)
  block_size = 16
  # Size of a key (in bytes)
  key_size = (16, 24, 32)
  解决方法就是将需要加密的数据Padding到16Byte的整数倍; 
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad

key=b1234567890123456cipher=AES.new(key,AES.MODE_CBC)

text=bsecret text
padtext=pad(text,16,style=‘pkcs7‘)
cipherText=cipher.encrypt(padtext)
print(padtext)
print(cipherText)

decrypter=AES.new(key,AES.MODE_CBC)
plaintext=decrypter.decrypt(cipherText)
print(plaintext)

 

问题三:每次加密得到的结果不一样

  这个问题的原因是AES CBC_MODE需要初始化向量。如果不指定初始化向量,则AES会在初始化时随机生成一个。这样就导致了每次加密得到的密文不一样;
        解决方法就是指定一个固定的初始化向量,同时也要注意解密时也使用同样的向量。

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad

key=b1234567890123456
iv=b‘abcdefghijklmnop‘
cipher=AES.new(key,AES.MODE_CBC,iv)

text=bsecret text
padtext=pad(text,16,style=pkcs7)
cipherText=cipher.encrypt(padtext)
print(padtext)
print(cipherText)

decrypter=AES.new(key,AES.MODE_CBC,iv)
plaintext=decrypter.decrypt(cipherText)
print(plaintext)

 

问题四:解密无法得到原始明文数据

  上面的程序运行出来发现后面还是跟着之前Paddding的数据,这是因为decrypt并不会将Padding的数据去掉。
  解决办法就是将解密的数据再进行unpad得到原始数据

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad

key=b1234567890123456
iv=babcdefghijklmnop
cipher=AES.new(key,AES.MODE_CBC,iv)

text=bsecret text
padtext=pad(text,16,style=pkcs7)
cipherText=cipher.encrypt(padtext)
print(padtext)
print(cipherText)

decrypter=AES.new(key,AES.MODE_CBC,iv)
plaintext=decrypter.decrypt(cipherText)
unpadtext=unpad(plaintext,16,‘pkcs7‘)
print(plaintext)
print(unpadtext)

 

经过上面的一系列的错误修正后,运行程序后可以得到正确的结果了

原始数据:secret text
padding数据:bsecret text\x05\x05\x05\x05\x05
加密数据:b\xb0\xb0\xd4h\xbc\x85\xd3\xd1>\x13\xdf\xa7AE(8
解密后数据:bsecret text

 


 

 

Python Crypto AES加密模式踩坑记

原文:https://www.cnblogs.com/linuxcat/p/14494630.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!