2

So I have generated a self signed certificate and a private key with OpenSSL.

Right now I am trying to:

a) print the public key as a string. This:

f = open(CERT_FILE)
cert_buffer = f.read()
f.close()
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_buffer)
pub_key = cert.get_pubkey()
print pub_key

Prints something like:

<OpenSSL.crypto.PKey object at 0x7f059864d058>

b) encrypt a string with this public key

c) decrypt the encrypted string with a private key

I would like to see some code examples. Please use only OpenSSL, no wrappers.

Richard Knop
  • 81,041
  • 149
  • 392
  • 552

1 Answers1

3

Is this what you want? It uses PyCrypto, not PyOpenSSL (I'm not sure if this is what you wanted to avoid when you mention no wrappers)

#!/usr/bin/env python

from Crypto.Cipher import AES
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA

def step1():
    rsaKey = RSA.importKey(open("./myKey.der", 'r'))
    print "Step 1: This is my rsa-key:\n%s" % rsaKey.exportKey()

def step2_encrypt(string):
    rsaKey = RSA.importKey(open("./myKey.der", 'r'))
    pkcs1CipherTmp = PKCS1_OAEP.new(rsaKey)
    encryptedString = pkcs1CipherTmp.encrypt(string)
    print "Step 2: encrypted %s is %s" % (string, encryptedString)
    return encryptedString

def step3_decrypt(encryptedString):
    rsaKey = RSA.importKey(open("./myKey.der", 'r'))
    pkcs1CipherTmp = PKCS1_OAEP.new(rsaKey)
    decryptedString = pkcs1CipherTmp.decrypt(encryptedString)
    print "Step 3: decryptedString %s is %s" % (encryptedString, decryptedString)
    return decryptedString


if __name__ == "__main__":
    step1()
    encryptedString = step2_encrypt("hello, duuude")
    decryptedString = step3_decrypt(encryptedString)
    print "Tadaaaa: %s" % decryptedString

The key files contain the public/private parts, so the encryption/decryption modules will know what to do.

Do you need the public/private key in two separate files (should be kind of straight forward, right)?

Be aware that when using asymmetric encryption, the maximum number of characters you can encrypt depends on the modulus used in your key. In the example above, if you use a regular RSA key (SHA-1, with 20 bytes modulus), you'll get errors for strings bigger than 214 bytes. As cyroxx pointed out in the comments, there's not theoretical limitation to the algorithm (you can encrypt long strings with very long keys) but the computational time it would take makes it pretty inviable for practical purposes.

If you need to cypher big chunks of data, you'll probably want to encrypt that data with a symmetric algorithm (like AES) and send the password encrypted with the RSA (asymmetric) keys along in the transferred data... but that's a different matter with a number of other issues :-)

Community
  • 1
  • 1
Savir
  • 17,568
  • 15
  • 82
  • 136
  • Who says that you can only encrypt short strings with asymmetric encryption? For longer chunks of data, it's only a matter of high computational cost - which in general is avoided by using hybrid cryptosystems. (As SO likes references, allow me to cite [Wikipedia](http://en.wikipedia.org/wiki/Public-key_cryptography#Computational_cost) here ;) – cyroxx Aug 02 '12 at 17:01
  • Well... the amount of characters that you can encrypt with an asymmetric key depends of the modulus of the key (http://lists.dlitz.net/pipermail/pycrypto/2008q3/000011.html) so... I guess you're technically right... You can encrypt longer chunks... With HUGE keys. So... if you wanna be *picky*, then... yeah, you can. You can try the example to encrypt a... 2kB string... see what happens. – Savir Aug 02 '12 at 17:16
  • No, I did not want to be picky. Just point out that it is theoretically possible. However, of course, in practical applications it works as you described. – cyroxx Aug 02 '12 at 17:21
  • 1
    @cyroxx: Correct, correct... You're indeed right: There's no theoretical limit to the algorithm. I should edit the response to clarify that... Meh... maybe... I'm feeling kinna lazy. – Savir Aug 02 '12 at 17:23