When I decrypt my string with the correct password following this simple guide on the library's website I get a correct string response. When I change the final w to an e to get an invalid key, I get a padding bytes error like this stemming from:
lib/python3.8/site-packages/cryptography/hazmat/primitives/padding.py", line 101, in _byte_unpadding_check
Which is then followed by the cryptography.fernet.InvalidToken error I was expecting.
ValueError: Invalid padding bytes.
During handling of the above exception, another exception occurred:
cryptography.fernet.InvalidToken
I've read Stackoverflow and can only find one example of this but it didn't seem to apply when this is just the actual example from their site.
What am I missing?
from cryptography.fernet import Fernet
# print(Fernet.generate_key()) # used this to get the below
bytes_key = b'tsuG7oqhwyCsfUof35btDJA2eM7AdGf4tAM0o1zXOew='
# changed just one digit of key to test incorrect key
# bytes_key = b'tsuG7oqhwyCsfUof35btDJA2eM7AdGf4tAM0o1zXOee='
f = Fernet(bytes_key)
# encrypt a message
# token = f.encrypt(b"A really secret message. Not for prying eyes.")
# print(token)
# b'gAAAAABiIOCx9Pp8HB9Asq0HUXb-t0SwX-W5ue7O3GJfuF9Rm4ue8I0Drk36NIyuZ0Mufknad5xkoL3091ZGOOS-QTqMbM-MeNrEC9jvmYx_Y0ojoSTaZWO9AXMJFZgdnvgPTB-wQIQd'
print(f.decrypt(b'gAAAAABiIOCx9Pp8HB9Asq0HUXb-t0SwX-W5ue7O3GJfuF9Rm4ue8I0Drk36NIyuZ0Mufknad5xkoL3091ZGOOS-QTqMbM-MeNrEC9jvmYx_Y0ojoSTaZWO9AXMJFZgdnvgPTB-wQIQd'))
print(f.decrypt(b'gAAAAABiIOCx9Pp8HB9Asq0HUXb-t0SwX-W5ue7O3GJfuF9Rm4ue8I0Drk36NIyuZ0Mufknad5xkoL3091ZGOOS-QTqMbM-MeNrEC9jvmYx_Y0ojoSTaZWO9AXMJFZgdnvgPTB-wQIQd').decode('utf-8'))
Details about the structure of the Fernet key, the Fernet token and the algorithms involved can be found here.
The Fernet key consists of the concatenation of a 16 bytes signing key and a 16 bytes encryption key, Base64url encoded.
For the posted valid Fernet key is:
Fernet key (Base64url): tsuG7oqhwyCsfUof35btDJA2eM7AdGf4tAM0o1zXOew=
Signing key (hex): b6cb86ee8aa1c320ac7d4a1fdf96ed0c
Encryption key (hex): 903678cec07467f8b40334a35cd739ec
and for the posted invalid key:
Fernet key (Base64url): tsuG7oqhwyCsfUof35btDJA2eM7AdGf4tAM0o1zXOee=
Signing key (hex): b6cb86ee8aa1c320ac7d4a1fdf96ed0c
Encryption key (hex): 903678cec07467f8b40334a35cd739e7
Note that both encryption keys differ in the last byte (0xec vs 0xe7), i.e. your change has modified the encryption key!
The wrong key causes that the decryption generates a wrong plaintext with a wrong padding. It is not the length of the padding that is wrong, but the values of the padding bytes themselves.
Details: The plaintext used in the example:
A really secret message. Not for prying eyes.
consists of 45 bytes, i.e. the padding consists of 3 bytes, namely the byte sequence 0x030303, since PKCS#7 padding is applied. For PKCS7# padding all padding bytes have the same value and this value corresponds to the number of padding bytes, for details see PKCS#7. If the ciphertext is decrypted with the wrong key, the last three bytes are 0x07e3f2, which does not correspond to a valid PKCS#7 padding and generates the ValueError: Invalid padding bytes error message.
Note: If the padding is correct, it is automatically removed.
Similarly, an invalid signing key generates a corresponding error message InvalidSignature: Signature did not match digest.
The padding 0x07e3f2 can be determined as follows:
The structure of the token is: version (1 byte) || timestamp (8 bytes) || IV (16 bytes) || ciphertext || HMAC (32 bytes). Thus, from the token, the IV and ciphertext below can be derived:
IV: f4fa7c1c1f40b2ad075176feb744b05f
ciphertext: e5b9b9eecedc625fb85f519b8b9ef08d03ae4dfa348cae67432e7e49da779c64a0bdf4f7564638e4be413a8c6ccf8c78
This allows decryption with AES/CBC without padding using the appropriate tools (e.g. here) and results in the following byte sequence for decryption with the wrong key:
6afb18a9791e407ce0eafd1d2c2ae1cef403e94903cf80e90193fafd0681e58f0e8fff0d3f3542901bced6fc8e07e3f2
with 0x07e3f2 as invalid padding bytes.
In contrast, if the correct key is supplied for decryption, the result is:
41207265616c6c7920736563726574206d6573736167652e204e6f7420666f7220707279696e6720657965732e030303
with the correct padding 0x030303.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With