Search code examples
pythonopenssl

'openssl rsa -in' command in python


I am trying to generate public key from private key generated using python subprocess.run() where I store the private key in a variable, not in a file. I want to use the same buffer variable as input to openssl rsa command as input which it can use to generate the public key. I am not sure how to pass this buffer in python code-

#generating private key and keeping it in a variable
filedata = subprocess.run(['openssl', 'genrsa', '4096'], check=True, stdout=subprocess.PIPE, universal_newlines=True).stdout

Now using that filedata in openssl rsa command, how to pass this in python command in os.system() or subprocess.run()

os.system("openssl rsa -in private.key -pubout > public.key")

Is it possible to pass private.key data from the variable which holds the data to openssl rsa? Here I am avoiding to store the private key contents in a file. That is why I am using the filedata variable.

thanks for your reply.


Solution

  • If you don't provide a -in option, then openssl rsa by default reads from stdin. So using subprocess.run, you can provide filedata as input using a command very similar to the one you're using to generate the private key.

    First, let's modify your private key generation so that we get bytes from subprocess.run instead of a string:

    filedata = subprocess.run(
        ["openssl", "genrsa", "4096"],
        check=True,
        stdout=subprocess.PIPE,
    ).stdout
    

    We can then pass filedata as input to openssl rsa -pubout ..., which in the absence of a -in option will read from stdin by default:

    subprocess.run(
        ["openssl", "rsa", "-pubout", "-out", "public.key"], input=filedata, check=True
    )
    

    Now you have the public key in file public.key. If you would rather have the public key in a variable instead of in a file, you can remove the -out public.key option, in which case the command is almost identical to the first one:

    pubkey = subprocess.run(
        ["openssl", "rsa", "-pubout"],
        input=filedata,
        check=True,
        stdout=subprocess.PIPE,
    ).stdout