Crypto.PublicKey: Public-Key Algorithms

So far, the encryption algorithms described have all been private key ciphers. The same key is used for both encryption and decryption so all correspondents must know it. This poses a problem: you may want encryption to communicate sensitive data over an insecure channel, but how can you tell your correspondent what the key is? You can't just e-mail it to her because the channel is insecure. One solution is to arrange the key via some other way: over the phone or by meeting in person.

Another solution is to use public-key cryptography. In a public key system, there are two different keys: one for encryption and one for decryption. The encryption key can be made public by listing it in a directory or mailing it to your correspondent, while you keep the decryption key secret. Your correspondent then sends you data encrypted with your public key, and you use the private key to decrypt it. While the two keys are related, it's very difficult to derive the private key given only the public key; however, deriving the private key is always possible given enough time and computing power. This makes it very important to pick keys of the right size: large enough to be secure, but small enough to be applied fairly quickly.

Many public-key algorithms can also be used to sign messages; simply run the message to be signed through a decryption with your private key key. Anyone receiving the message can encrypt it with your publicly available key and read the message. Some algorithms do only one thing, others can both encrypt and authenticate.

The currently available public-key algorithms are listed in the following table:


23#23

Many of these algorithms are patented. Before using any of them in a commercial product, consult a patent attorney; you may have to arrange a license with the patent holder.

An example of using the RSA module to sign a message:

>>> from Crypto.Hash import MD5
>>> from Crypto.PublicKey import RSA
>>> RSAkey = RSA.generate(384, randfunc)   # This will take a while...
>>> hash = MD5.new(plaintext).digest()
>>> signature = RSAkey.sign(hash, "")
>>> signature   # Print what an RSA sig looks like--you don't really care.
('\021\317\313\336\264\315' ...,)
>>> RSAkey.verify(hash, signature)     # This sig will check out
1
>>> RSAkey.verify(hash[:-1], signature)# This sig will fail
0

Public-key modules make the following functions available:


24#24


25#25

If you want to interface with some other program, you will have to know the details of the algorithm being used; this isn't a big loss. If you don't care about working with non-Python software, simply use the pickle module when you need to write a key or a signature to a file. It's portable across all the architectures that Python supports, and it's simple to use.

Public-key objects always support the following methods. Some of them may raise exceptions if their functionality is not supported by the algorithm.


26#26


27#27


28#28


29#29


30#30


31#31


32#32


33#33


34#34


35#35



Subsections