Ñhosko
Ñhosko

Reputation: 795

Using the less-than (<) symbol on Python's subprocess

Directly on console I can encrypt and decrypt a string using openssl. As openssl requires an input file, I can tell it to get this from the echo I enter using the less-than symbol (<), like this:

Encrypt:

# openssl enc -aes-256-cbc -in <(echo "helloworld") -a -k 12345678 -S 12345678 -iv 12345678
U2FsdGVkX18SNFZ4AAAAAKJTAirWf4KnDHYXlIF/87Y=

Decrypt:

# openssl enc -aes-256-cbc -in <(echo "U2FsdGVkX18SNFZ4AAAAAKJTAirWf4KnDHYXlIF/87Y=") -d -a -k 12345678 -S 12345678 -iv 12345678
helloworld

Using Python I need to decrypt the string "U2FsdGVkX18SNFZ4AAAAAKJTAirWf4KnDHYXlIF/87Y=" and to print out "helloworld".

So far, I've tried this but I get always an error:

from subprocess import Popen, PIPE
cmd = 'openssl enc -aes-256-cbc -in < (echo U2FsdGVkX18SNFZ4AAAAAKJTAirWf4KnDHYXlIF/87Y=) ' \
      '-d -a -k 12345678 -S 12345678 -iv 12345678'
x = Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = x.communicate()[0]
print output

The error I get is: /bin/sh: 1: Syntax error: "(" unexpected

Is there a way of achieving what I need?

Upvotes: 2

Views: 1342

Answers (3)

glibdud
glibdud

Reputation: 7840

Python is using /bin/sh by default to execute your command, but sh doesn't support the <(...) construct. You need to use another shell (e.g. bash) instead, using Popen's executable argument:

>>> x = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, executable='/bin/bash')
>>> x.communicate()
('U2FsdGVkX18SNFZ4AAAAAKJTAirWf4KnDHYXlIF/87Y=\n', None)

(That said, I would consider exploring deceze's suggestion of using a more pythonic method of providing input.)

Upvotes: 2

Pobe
Pobe

Reputation: 2793

Have you tested the command directly in a shell to see if it worked?

Finally, there's nothing that seems to block you from separating those calls.

You could echo U2FsdGVkX18SNFZ4AAAAAKJTAirWf4KnDHYXlIF/87Y and pass this to stdin=subprocess.PIPE from an other subprocess, that has the openssl command in it.

Upvotes: -1

deceze
deceze

Reputation: 522085

$ openssl enc --help
...
 -in file           Input file to read from (default stdin)

The command reads from stdin by default, you only need the -in parameter if you want openssl to read from a file instead of a pipe. I.e., by default this would do just fine too:

echo helloworld | openssl enc ...
# (no -in!)

The Python equivalent of this is:

x = Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = x.communicate(input='helloworld')[0]

(Again, no -in in cmd, let openssl read from stdin.)

Upvotes: 2

Related Questions