views:

646

answers:

3

How do I verify the correct key is being used to decrypt AES encrypted data using pyCrypto AES?

cipher = AES.new(key, AES.MODE_CFB)
cipher.decrypt(s)

If an incorrect key is used, it still attempts to decrypt the data, obfuscating it more. Is there any test I can do to prove the data is being decrypted to the original state?

A: 

I don't believe you can [tell if the key is correct], with the AES context alone.
i.e. you can't, other than by verifying the format and/or some message digest value for the clear text after it is decoded, which implies that you know such structure or message digest.

Although this is merely a consequence of the way the algorithm/protocol is established, one of the benefits of this is that this makes brute-force attacks on such ciphers more difficult because one needs to take the time and decode at least part of the message and also to pass it through a clear-text detector. The clear-text detector is some logic that has a-priori/guessed understanding of the nature of the cleartext, and which can tell if the data meets this expectation; for example a simple detector may check that the first 20 bytes are US ASCII). This is particularly useful with multiple encoding schemes like triple DES where one has no clue (well cryptanalysis geniuses may have a mild idea...) of what the intermediate "clear-texts" look like.

Edit: to answer OP's questions in the notes
Yes, if you are unsure of the key, you need to make a copy of the ciphertext before attempting to get it decoded. It will return as real gibberish (and not easily reversible, if at all) if it is decoded with the wrong key.
To introduce a way of detecting the validity of the decoded message, for both binary and ASCII/text messages, you can use a variation on the the following "envellope" concept.
Note: This may [mildly] weaken the strength of your cryptographic setup.
This assumes that you have control or collaboration over the encoding process as well. This works for both ASCII and binary content
The idea is simply to add a prefix (a "header"), and possibly a suffix ("trailer") to the message. To be cryptographically safer such a prefix should be long enough (say 500 bytes?) and have most of its content be random in nature. You then would need to insert the actual message in this "enveloppe" and assert the validity/integrity of the envelope after decription. Tentative example:

17 random bytes
2 bytes length of this header  (allows to have a variable length header)
1 byte offset to "fingerprint"
x random bytes
fingerprint = a short binary (preferably) or ascii constant text  "MyDataIsOk"
[optionally: length of the payload and/or a CRC / MD5 / digest-of-sort for it]
y random bytes
followed by the actual message

A simplistic (but a bit "dangerous" for the crypto) is simply to add, say, "MyDataIsGood123ABC" in front of the data. At decryption time you'd verify that the decrypted stream starts with these 16 bytes bytes, and you'd remove them to get the actual message.

mjv
Thx, an ASCII test will probably do, any idea how I'd test if a binary file is encrypted? If not I'll need to write in some sort of test case before proceeding with the entire file?
zyrus001
Would building a test case into my code make the encryption pointless? ie, if cipher.decrypt(s) == 'Flag': 'Correct Key' :- I need to avoid ruining the data if the key is wrong.
zyrus001
@zyrus001 see edit with idea for asserting validity/integrity of the message. Also, yes, you'd need to make a copy of the ciphertext if you're unsure of the key.
mjv
+2  A: 

A typical way to achieve this would be using an HMAC.

Craig McQueen
A: 

Take a look at this blog post, it includes example code for doing what you need (ie. CRC)
Python symmetric encryption with CRC

Alon Swartz
May I ask, why you proposed a scheme that has long been known to be weak? E.g.,among many others by Stubblebine and Gligor in their paper "On message integrity in cryptographic protocols",Symposium on Research in Security and Privacy. 1992.
Accipitridae