Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private/Public Encryption in Python with Standard Library

Tags:

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.

like image 438
Noctis Skytower Avatar asked Dec 16 '11 19:12

Noctis Skytower


People also ask

Can you encrypt with private key and decrypt with public key?

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.


2 Answers

Public key encryption is not in the standard library. There are some third party libraries on PyPi for it though:

  • PyCrypto
  • RSA Python

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) 
like image 88
Raymond Hettinger Avatar answered Sep 19 '22 13:09

Raymond Hettinger


PyCrypto works on Python 3 as of 2.4.1.

like image 40
nmichaels Avatar answered Sep 18 '22 13:09

nmichaels