Search code examples
python-3.xpycrypto

How to import RSA keys by command line argument?


I have been using Pycrypto module to generate RSA public/private key pair and trying to import keys by sending the public key as command line argument:

from Crypto.PublicKey import RSA
from Crypto import Random
import sys

input_key = sys.argv[1]
print('\n')
print(type(input_key))
print('\n')
print(input_key)
print('\n')

public_key = RSA.importKey(input_key)
print(type(public_key))

but I get the output:

$ python3 encrypt.py '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaIRYO3hxr0ObcYcgKtxFequ6p\n9HVV8E95ghUUHmydVJYy16Ip9F6ik7G8wBU7X3VIfjdxHAtrwY9doCy8Ype6NNio\nS/ErGRtUQ1jgyT2f9okIdroEipnh1zwbXQcxveaxlwBhp7OFGZ/0W3FKgJLYtyzW\nEhfPO+8GkT0eLH5FaQIDAQAB\n-----END'
  >>> <class 'str'>

-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaIRYO3hxr0ObcYcgKtxFequ6p\n9HVV8E95ghUUHmydVJYy16Ip9F6ik7G8wBU7X3VIfjdxHAtrwY9doCy8Ype6NNio\nS/ErGRtUQ1jgyT2f9okIdroEipnh1zwbXQcxveaxlwBhp7OFGZ/0W3FKgJLYtyzW\nEhfPO+8GkT0eLH5FaQIDAQAB\n-----END PUBLIC KEY-----

   Traceback (most recent call last):
File "encrypt.py", line 13, in <module>
  public_key = RSA.importKey(input_key)
File "/usr/lib/python3/dist-packages/Crypto/PublicKey/RSA.py", line 638, in importKey
if lines[1].startswith(b('Proc-Type:4,ENCRYPTED')):
  IndexError: list index out of range

But when I copy paste the same key into Python Interpreter, I get these:

>>> input_key = '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaIRYO3hxr0ObcYcgKtxFequ6p\n9HVV8E95ghUUHmydVJYy16Ip9F6ik7G8wBU7X3VIfjdxHAtrwY9doCy8Ype6NNio\nS/ErGRtUQ1jgyT2f9okIdroEipnh1zwbXQcxveaxlwBhp7OFGZ/0W3FKgJLYtyzW\nEhfPO+8GkT0eLH5FaQIDAQAB\n-----END PUBLIC KEY-----'
>>> pub_key = RSA.importKey(input_key)
>>> type(pub_key)
    <class 'Crypto.PublicKey.RSA._RSAobj'>

How to import them as a command line argument ?


Solution

  • When you execute

    $ python3 encrypt.py '-----BEGIN PUBLIC KEY-----\nMIG...'
    

    the shell does not interpret \n as newline escapes, but as literal backslash+n, and that's what your program sees within sys.argv[1].

    You can have newlines within en escaped shell string, so this should work:

    $ python3 encrypt.py '-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaIRYO3hxr0ObcYcgKtxFequ6p
    9HVV8E95ghUUHmydVJYy16Ip9F6ik7G8wBU7X3VIfjdxHAtrwY9doCy8Ype6NNio
    S/ErGRtUQ1jgyT2f9okIdroEipnh1zwbXQcxveaxlwBhp7OFGZ/0W3FKgJLYtyzW
    EhfPO+8GkT0eLH5FaQIDAQAB
    -----END PUBLIC KEY-----'
    

    If you really want to use a string with escapes, you can either handle the escapes yourself in your program by doing input_key = sys.argv[1].replace('\\n', '\n'), or let the shell do the escaping e.g by passing the string through echo: $ python3 encrypt.py "$(echo -ne '-----BEGIN PUBLIC KEY-----\nMIG...')".