I'm doing a brute-force decryption exercise, and I'm relatively new to Python. My code works perfectly well when I do this openSSL decryption call to a test file when I know the key. However, the exercise that I am doing requires me to iterate through all possible values of a key, sending the openSSL call with each possible value.
for x in range(0,10):
for y in range(0,10):
key = "pass:" + str(x) + str(y)
plaintext = subprocess.check_output(['openssl', 'aes-128-cbc', '-d', '-in', 'ciphertext', '-base64', '-pass', key])
print (plaintext)
Knowing that all but one of my attempts will fail to decrypt, I am struggling with handling the openssl return values in a way that my python script won't crash. For example, if the first attempt fails to decrypt (which it almost certainly will), openssl returns 'bad decrypt' along with some other junk. I simply want to throw this attempt away and move to the next iteration. But instead, my program crashes like this:
bad decrypt
140735254008672:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:
Traceback (most recent call last):
File "/Users/.../Project.py", line 20, in <module>
plaintext = subprocess.check_output(['openssl', 'aes-128-cbc', '-d', '-in', CIPHERTEXT_FILE, '-base64', '-pass', key])
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/subprocess.py", line 589, in check_output
raise CalledProcessError(retcode, process.args, output=output)
subprocess.CalledProcessError: Command '['openssl', 'aes-128-cbc', '-d', '-in', 'proj0.enc', '-base64', '-pass', 'pass:xx']' returned non-zero exit status 1
I can't even check for the string bad decrypt because the program has already crashed.
Can anyone help me. I'm pretty new to Python, so I'm spinning my wheels. Thanks!
2 Answers 2
Use try/except
for x in range(0,10):
for y in range(0,10):
key = "pass:" + str(x) + str(y)
try:
plaintext = subprocess.check_output(['openssl', 'aes-128-cbc', '-d', '-in', 'ciphertext', '-base64', '-pass', key])
except subprocess.CalledProcessError as e:
print("{key} failed".format(key=key))
else:
print (plaintext)
3 Comments
During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/randy/Development/ADT_Workspace/NetworkSecurityProject00/Project0/Project0.py", line 24, in <module> print("{key} failed".format(key)) KeyError: 'key'print("{key} failed".format(key=key)). The key=key is key! ;)According to the docs: check_output
"If the return code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and any output in the output attribute."
So you can use try/catch and examine the output attribute of the exception object.
Alternatively, you can use subprocess.Popen() with stdout=PIPE and .communicate() to get the output regardless of the return value. You can then search the output for expected strings yourself.