Hello everyone.
I am trying to play a bit with RSA public and private keys and encryption/decryption with PyCrypto and I have encountered and issue that seems kind of strange to me (it probably makes a lot of sense the way it's working now, but I don't know much about RSA asymmetric encryption and that's why it's puzzling me). It is the inability I have encountered to decrypt something having only the public key.
Here's the thing: I have a server and a client. I want the server to "recognize" and register the client and show it in a list of "known devices". The client will have the public key of the server and the server will have the public key of the client, so when the client communicates with the server, it will encrypt its data with his client's private key and with the server's public key. By doing this, only the proper server will be able to open the data (with its private key) and will be able to verify that the sender is actually the client that claims to be... well... or at least, that's what I think, because I'm pretty newbie in this asymmetric encryption. The idea is that when one of those clients wakes up, it will send its public key (encrypted with the server's public key, of course, but that's probably not relevant at this point... yet) saying "Hey, I'm a new client and this is my public key. Register that key with my UUID" and the server will obey, associating that public key with the client's UUID and use that key to decrypt data coming from that client. I just want to transmit the client's public key, keeping its private key secret, secret, secret (it's private, right?)
I am doing some tests with openssl and very simple Python scripts that use PyCrypto (actually, not even in a server/client architecture or anything... just trying to encrypt something with a private key and decrypt it with the public key)
First of all, I have created a public/private key set with:
openssl genrsa -out ~/myTestKey.pem -passout pass:"f00bar" -des3 2048
Ok, first thing that puzzles me a bit... It generates only one file, with both the private and the public keys... Well... O'right... whatever. I can extract the public key with:
openssl rsa -pubout -in ~/myTestKey.pem -passin pass:"f00bar" -out ~/myTestKey.pub
So I thought I had my couple of private (private+public, actually) and public keys in ~/myTestKey.pem
and ~/myTestKey.pub
respectively. Well... apparently I'm doing something wrong, because PyCrypto doesn't like this assembly. And I don't know why.
I have two very simple test scripts, "encryptor.py
" and "decryptor.py
". The "encryptor.py
" should encrypt something with the private key, and "decryptor.py
", decrypt it with the public key. I know... I'm a parangon of originality...
So, I encrypt the string "Loren ipsum" with my "encryptor.py
" (with private key):
----------- encryptor.py ----------------
#!/usr/bin/python
from Crypto.PublicKey import RSA
def encrypt(message):
externKey="/home/borrajax/myTestKey.pem"
privatekey = open(externKey, "r")
encryptor = RSA.importKey(privatekey, passphrase="f00bar")
encriptedData=encryptor.encrypt(message, 0)
file = open("/tmp/cryptThingy.txt", "wb")
file.write(encriptedData[0])
file.close()
if __name__ == "__main__":
encryptedThingy=encrypt("Loren ipsum")
And it works fine. Well... I suppose so, because in the file "/tmp/cryptThingy.txt
" I get a lot of gibberish. It looks really, really encrypted to me.
But when I try to decrypt it using just the file that contains just the public key...
----------- decryptor.py ---------------
#!/usr/bin/python
from Crypto.PublicKey import RSA
def decrypt():
externKey="/home/borrajax/myTestKey.pub"
publickey = open(externKey, "r")
decryptor = RSA.importKey(publickey, passphrase="f00bar")
retval=None
file = open("/tmp/cryptThingy.txt", "rb")
retval = decryptor.decrypt(file.read())
file.close()
return retval
if __name__ == "__main__":
decryptedThingy=decrypt()
print "Decrypted: %s" % decryptedThingy
... PyCrypto yells at me with a:
File "/usr/local/lib/python2.7/dist-packages/pycrypto-2.5-py2.7-linux-i686.egg/Crypto/PublicKey/RSA.py", line 107, in _decrypt
mp = self.key._decrypt(cp)
TypeError: Private key not available in this object
Yeah, of course it's not available! I extracted the public key! It took me 2 hours finding how to do it properly!!
What am I missing? As I said, I'm pretty newbie in this public/private asymmetric key encryption so I might have a core "conceptual error"... Any hint will be appreciated.
¡Thank you in advance!
Cipher.PKCS1_OAEP
module to encrypt/decrypt. It will apply a secure padding to your message. Don't use the encrypt/decrypt method of the RSA key itself. See here: dlitz.net/software/pycrypto/api/current/… – SquareRootOfTwentyThree