This is extremely strange but I have already tried this twice and am completely sure it is openSSL and not me doing the bug. I am encrypting the data 'Hygiene' with the password '*' (sorry can't tell you this) and get the ciphertext '3/mEwtZdIuIV5wwsQAcnAw==' then I changed the last charecter to '-' and when I decrypted it still decrypted normally!. I then tried changing it to different things such as '+' but it didn't work, Is this supposed to be so? Or have I just found another bug in openSSL?
2 Answers
You have not found a bug in OpenSSL, not a real one. You may have found a gap in your understanding, though.
Namely, encryption works on bytes and produces bytes. What you see with your eyes are characters. In order to accommodate character-oriented devices (e.g. your eyes), OpenSSL applies an extra encoding on the encryption output: it takes the bytes and turns them into characters, using Base64.
Base64 turns every group of three bytes into a sequence of four characters. The characters are taken from letters (uppercase and lowercase), digits, '+' and '/'. However, the input length might not be a multiple of 3; in your case, the AES output is 16 bytes. The first 15 bytes (5 groups of 3) are Base64-encoded into 20 characters (5 sequences of 4 characters). The remaining lone byte is encoded again as 4 characters, but with a special rule: the last two characters will be '=' signs.
Now, when you modify the second '=' and replace it with a '-', then you are turning your string into something which is not valid Base64; yet OpenSSL will still try to recover from it and decode bytes out of it. In fact, the way OpenSSL works is the following: it first removes all characters that are not part of the 64 "normal" Base64 characters (letters, digits, '+' and '/'). It then proceeds from what remains (here, 22 characters). If you replace a '=' with a '-', then you are just replacing a character that OpenSSL removes, with another character that OpenSSL removes as well; therefore, things keep on working. However, if you replace a '=' with a '+', then OpenSSL will keep that '+' and end up with 23 characters, which, upon decoding, will yield 17 bytes, not 16. AES won't like an input whose length is not a multiple of 16.
All of this is about encoding: transforming bytes into characters, and back. Encryption is not relevant here.
-
+1 thanks a lot I knew the basic inner design of AES but not that it got encoded thanks! Apr 18, 2014 at 15:21
The trailing ==
is the Base64 indicator for the end of the encoded data.
There's a technical difference between ending with =
and ==
, involving how many bytes are in the last block (24 bits), but your bytes may line up such that it doesn't matter. You're causing OpenSSL to interpret your Base64 string as 3/mEwtZdIuIV5wwsQAcnAw=
with some trailing garbage.
In short: This is not a problem.