(TL;DR at the end)
Let's say the plaintext hello
is encrypted with AES (CFB mode). I noticed that decryption works no matter the given password! Of course if the password is wrong, the output will be garbage, but no error will be thrown (example in Python):
import Crypto, Crypto.Random, Crypto.Hash, Crypto.Cipher.AES
p = b'hello'
iv = Crypto.Random.new().read(Crypto.Cipher.AES.block_size)
cipher = Crypto.Cipher.AES.new(Crypto.Hash.SHA256.new(b'password1').digest(),
Crypto.Cipher.AES.MODE_CFB, iv).encrypt(p)
print(Crypto.Cipher.AES.new(Crypto.Hash.SHA256.new(b'wrongpassword').digest(),
Crypto.Cipher.AES.MODE_CFB, iv).decrypt(cipher))
# b'\xfdQ\xd7\xa3\x1b'
I read that HMAC etc. can be used to ensure integrity, or AES in GCM mode.
But to keep things simple, I wanted to know if this method is secure or not:
p = b'hello'
startingtag = b'504B0304' # fixed constant, like "MZ" for DOS .exe files, or "%PDF-1.5" for PDF files
iv = Crypto.Random.new().read(Crypto.Cipher.AES.block_size)
cipher = Crypto.Cipher.AES.new(Crypto.Hash.SHA256.new(b'password1').digest(),
Crypto.Cipher.AES.MODE_CFB, iv).encrypt(startingtag + p)
s = Crypto.Cipher.AES.new(Crypto.Hash.SHA256.new(b'wrongpassword1').digest(),
Crypto.Cipher.AES.MODE_CFB, iv).decrypt(cipher)
if s[:len(startingtag)] == startingtag:
print('ok good password, here is the plaintext:')
print(s[len(startingtag):])
else:
print('wrong password entered.')
What does it do? A starting tag is encrypted along the plaintext. Then we check if the first bytes of the decrypted text matches this starting tag.
This is basically the method explained here. I had the same questionning than a comment there:
if the first block of the plaintext is a known value, can't an attacker easily get the key from looking at the first block of the ciphertext?
But on the other hand this seems true as well:
Having a known header isn't a problem, otherwise encrypting something like a Microsoft Word document (that also has a known header) would be insecure.
TL;DR:
- Is it secure to encrypt with AES CFB mode a plaintext for which the first bytes are known (e.g.
%PDF-1.5
for a PDF document), - or does this give too much information to an attacker? Then does this mean it's a bad to encrypt documents with known headers with AES?
Crypto.Random...
line is pointless; just useos.urandom(128)
. It's the same. $\endgroup$