我的目标是拥有一个非常简单的AES 128 CBC方案,该方案对明文进行加密,然后根据Python中的给定密钥对其进行解密。我正在使用pycryptodome框架,我找不到任何带有AES CBC方案示例的文档。
以下是我的代码。解密的数据与加密前的数据不同。如果有人能帮助我找出这里出了什么问题,那将会很棒。
def block
user = User.find(params[:id])
user.update(active: params[:value])
end
答案 0 :(得分:3)
如t.m.adam所述,CBC操作模式需要初始化向量(IV)才能工作。因为IV通常被遗忘(也必须是唯一且不可预测的,例如随机的),所以当初始化密码对象时,Pycryptodome会创建一个随机的。
对于每个加密,IV必须是唯一的,并且是解密所必需的。通常的做法(来源?)是将IV放在密文的开头(IV不需要保密)。
使您的示例有效:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
# Do not use raw passwords as keys,
# use a derivation functions to generate keys from them
key = b'Sixteen byte key'
data = 'Jeevan B Manoj'.encode("UTF-8")
data = pad(data, AES.block_size)
encryptor = AES.new(key, AES.MODE_CBC)
iv = encryptor.IV
decryptor = AES.new(key, AES.MODE_CBC, IV=iv)
ciphertext = encryptor.encrypt(data)
plaintext = decryptor.decrypt(ciphertext)
assert plaintext == data
重要说明:为了安全起见,密文和IV必须经过身份验证(因此数据无法被篡改)。为此,Pycryptodome提供了像Hans-Peter Jansen on GitHub所指出的EAD和GCM等AEAD模式。对于他们中的许多人来说,不需要填充。
答案 1 :(得分:0)
如果使用MODE_ECB而不是MODE_CBC,则可以使用。我也不知道你正在使用什么填充例程,所以我使用了这个。 我在这里有几个其他的例子: https://github.com/SolarDon/pycryptodome/tree/master/Examples
from Crypto.Cipher import AES
# Padding for the input string --not related to encryption itself.
BLOCK_SIZE = 16 # Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
key = b'Sixteen byte key'
data = 'Jeevan B Manoj'.encode("UTF-8")
data = pad(data)
cipher = AES.new(key, AES.MODE_ECB) # AES.MODE_CBC
print("data before encryption")
print(data)
ciphertext = cipher.encrypt(data)
cipher = AES.new(key, AES.MODE_ECB) # MODE_CBC
plaintext = cipher.decrypt(ciphertext)
print(unpad(plaintext))