Is there a module that has my searching has been unable to discover that would allow writing code like the following? The reason for wanting to write code like this is unimportant. All I am after is some code that has a simple API to generate public and private byte keys and to easily encode and decode data with those keys.
import module, os method, bits, data = 'RSA', 1024, os.urandom(1024) public, private = module.generate_keys(method, bits) assert isinstance(public, bytes) and isinstance(private, bytes) assert module.decode(module.encode(data, private), public) == data assert module.decode(module.encode(data, public), private) == data
Most of what appears to be available requires downloading a package and only runs on Python 2.x. It is also quite common to find libraries that work with PEM files or other types of certificates. I would like to avoid having to deal with such files, to generate public and private keys on the fly, and quickly work with data in memory.
Anyone can encrypt a message by using your public key, but only you can read it. When you receive the message, you decrypt it by using your private key. Similarly, you can encrypt a message for anyone else by using their public key, and they decrypt it by using their private key.
Public key encryption is not in the standard library. There are some third party libraries on PyPi for it though:
If you're interested in the math behind it, Python makes it easy to experiment:
code = pow(msg, 65537, 5551201688147) # encode using a public key plaintext = pow(code, 109182490673, 5551201688147) # decode using a private key
The key generation is a little more involved. Here is a simplified example of how to do key generation in-memory using urandom as the source of entropy. The code runs under both Py2.6 and Py3.x:
import random def gen_prime(N=10**8, bases=range(2,20000)): # XXX replace with a more sophisticated algorithm p = 1 while any(pow(base, p-1, p) != 1 for base in bases): p = random.SystemRandom().randrange(N) return p def multinv(modulus, value): '''Multiplicative inverse in a given modulus >>> multinv(191, 138) 18 >>> 18 * 138 % 191 1 ''' # http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm x, lastx = 0, 1 a, b = modulus, value while b: a, q, b = b, a // b, a % b x, lastx = lastx - q * x, x result = (1 - lastx * modulus) // value return result + modulus if result < 0 else result def keygen(N): '''Generate public and private keys from primes up to N. >>> pubkey, privkey = keygen(2**64) >>> msg = 123456789012345 >>> coded = pow(msg, 65537, pubkey) >>> plain = pow(coded, privkey, pubkey) >>> assert msg == plain ''' # http://en.wikipedia.org/wiki/RSA prime1 = gen_prime(N) prime2 = gen_prime(N) totient = (prime1 - 1) * (prime2 - 1) return prime1 * prime2, multinv(totient, 65537)
PyCrypto works on Python 3 as of 2.4.1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With