• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _usage:
2
3Usage
4=====
5
6This section describes the usage of the Python-RSA module.
7
8Before you can use RSA you need keys. You will receive a private key
9and a public key.
10
11.. important::
12
13    The private key is called *private* for a reason. Never share this
14    key with anyone.
15
16The public key is used for encrypting a message such that it can only
17be read by the owner of the private key. As such it's also referred to
18as the *encryption key*. Decrypting a message can only be done using
19the private key, hence it's also called the *decryption key*.
20
21The private key is used for signing a message. With this signature and
22the public key, the receiver can verify that a message was signed
23by the owner of the private key, and that the message was not modified
24after signing.
25
26
27Generating keys
28---------------
29
30You can use the :py:func:`rsa.newkeys` function to create a keypair:
31
32    >>> import rsa
33    >>> (pubkey, privkey) = rsa.newkeys(512)
34
35Alternatively you can use :py:meth:`rsa.PrivateKey.load_pkcs1` and
36:py:meth:`rsa.PublicKey.load_pkcs1` to load keys from a file:
37
38    >>> import rsa
39    >>> with open('private.pem', mode='rb') as privatefile:
40    ...     keydata = privatefile.read()
41    >>> privkey = rsa.PrivateKey.load_pkcs1(keydata)
42
43
44Time to generate a key
45++++++++++++++++++++++
46
47Generating a keypair may take a long time, depending on the number of
48bits required. The number of bits determines the cryptographic
49strength of the key, as well as the size of the message you can
50encrypt. If you don't mind having a slightly smaller key than you
51requested, you can pass ``accurate=False`` to speed up the key
52generation process.
53
54Another way to speed up the key generation process is to use multiple
55processes in parallel to speed up the key generation. Use no more than
56the number of processes that your machine can run in parallel; a
57dual-core machine should use ``poolsize=2``; a quad-core
58hyperthreading machine can run two threads on each core, and thus can
59use ``poolsize=8``.
60
61    >>> (pubkey, privkey) = rsa.newkeys(512, poolsize=8)
62
63These are some average timings from my desktop machine (Linux 2.6,
642.93 GHz quad-core Intel Core i7, 16 GB RAM) using 64-bit CPython 2.7.
65Since key generation is a random process, times may differ even on
66similar hardware. On all tests, we used the default ``accurate=True``.
67
68+----------------+------------------+------------------+
69| Keysize (bits) | single process   | eight processes  |
70+================+==================+==================+
71| 128            | 0.01 sec.        | 0.01 sec.        |
72+----------------+------------------+------------------+
73| 256            | 0.03 sec.        | 0.02 sec.        |
74+----------------+------------------+------------------+
75| 384            | 0.09 sec.        | 0.04 sec.        |
76+----------------+------------------+------------------+
77| 512            | 0.11 sec.        | 0.07 sec.        |
78+----------------+------------------+------------------+
79| 1024           | 0.79 sec.        | 0.30 sec.        |
80+----------------+------------------+------------------+
81| 2048           | 6.55 sec.        | 1.60 sec.        |
82+----------------+------------------+------------------+
83| 3072           | 23.4 sec.        | 7.14 sec.        |
84+----------------+------------------+------------------+
85| 4096           | 72.0 sec.        | 24.4 sec.        |
86+----------------+------------------+------------------+
87
88If key generation is too slow for you, you could use OpenSSL to
89generate them for you, then load them in your Python code. OpenSSL
90generates a 4096-bit key in 3.5 seconds on the same machine as used
91above. See :ref:`openssl` for more information.
92
93
94Encryption and decryption
95-------------------------
96
97To encrypt or decrypt a message, use :py:func:`rsa.encrypt` resp.
98:py:func:`rsa.decrypt`. Let's say that Alice wants to send a message
99that only Bob can read.
100
101#. Bob generates a keypair, and gives the public key to Alice. This is
102   done such that Alice knows for sure that the key is really Bob's
103   (for example by handing over a USB stick that contains the key).
104
105    >>> import rsa
106    >>> (bob_pub, bob_priv) = rsa.newkeys(512)
107
108#. Alice writes a message, and encodes it in UTF-8. The RSA module
109   only operates on bytes, and not on strings, so this step is
110   necessary.
111
112    >>> message = 'hello Bob!'.encode('utf8')
113
114#. Alice encrypts the message using Bob's public key, and sends the
115   encrypted message.
116
117    >>> import rsa
118    >>> crypto = rsa.encrypt(message, bob_pub)
119
120#. Bob receives the message, and decrypts it with his private key.
121
122    >>> message = rsa.decrypt(crypto, bob_priv)
123    >>> print(message.decode('utf8'))
124    hello Bob!
125
126Since Bob kept his private key *private*, Alice can be sure that he is
127the only one who can read the message. Bob does *not* know for sure
128that it was Alice that sent the message, since she didn't sign it.
129
130
131RSA can only encrypt messages that are smaller than the key. A couple
132of bytes are lost on random padding, and the rest is available for the
133message itself. For example, a 512-bit key can encode a 53-byte
134message (512 bit = 64 bytes, 11 bytes are used for random padding and
135other stuff). See :ref:`bigfiles` for information on how to work with
136larger files.
137
138Altering the encrypted information will *likely* cause a
139:py:class:`rsa.pkcs1.DecryptionError`. If you want to be *sure*, use
140:py:func:`rsa.sign`.
141
142    >>> crypto = rsa.encrypt(b'hello', bob_pub)
143    >>> crypto = crypto[:-1] + b'X' # change the last byte
144    >>> rsa.decrypt(crypto, bob_priv)
145    Traceback (most recent call last):
146    ...
147    rsa.pkcs1.DecryptionError: Decryption failed
148
149
150.. warning::
151
152    Never display the stack trace of a
153    :py:class:`rsa.pkcs1.DecryptionError` exception. It shows where
154    in the code the exception occurred, and thus leaks information
155    about the key. It’s only a tiny bit of information, but every bit
156    makes cracking the keys easier.
157
158Low-level operations
159++++++++++++++++++++
160
161The core RSA algorithm operates on large integers. These operations
162are considered low-level and are supported by the
163:py:func:`rsa.core.encrypt_int` and :py:func:`rsa.core.decrypt_int`
164functions.
165
166Signing and verification
167------------------------
168
169You can create a detached signature for a message using the
170:py:func:`rsa.sign` function:
171
172    >>> (pubkey, privkey) = rsa.newkeys(512)
173    >>> message = 'Go left at the blue tree'
174    >>> signature = rsa.sign(message, privkey, 'SHA-1')
175
176This hashes the message using SHA-1. Other hash methods are also
177possible, check the :py:func:`rsa.sign` function documentation for
178details. The hash is then signed with the private key.
179
180It is possible to calculate the hash and signature in separate operations
181(i.e for generating the hash on a client machine and then sign with a
182private key on remote server). To hash a message use the :py:func:`rsa.compute_hash`
183function and then use the :py:func:`rsa.sign_hash` function to sign the hash:
184
185    >>> message = 'Go left at the blue tree'
186    >>> hash = rsa.compute_hash(message, 'SHA-1')
187    >>> signature = rsa.sign_hash(hash, privkey, 'SHA-1')
188
189In order to verify the signature, use the :py:func:`rsa.verify`
190function. This function returns True if the verification is successful:
191
192    >>> message = 'Go left at the blue tree'
193    >>> rsa.verify(message, signature, pubkey)
194    True
195
196Modify the message, and the signature is no longer valid and a
197:py:class:`rsa.pkcs1.VerificationError` is thrown:
198
199    >>> message = 'Go right at the blue tree'
200    >>> rsa.verify(message, signature, pubkey)
201    Traceback (most recent call last):
202      File "<stdin>", line 1, in <module>
203      File "/home/sybren/workspace/python-rsa/rsa/pkcs1.py", line 289, in verify
204        raise VerificationError('Verification failed')
205    rsa.pkcs1.VerificationError: Verification failed
206
207.. warning::
208
209    Never display the stack trace of a
210    :py:class:`rsa.pkcs1.VerificationError` exception. It shows where
211    in the code the exception occurred, and thus leaks information
212    about the key. It's only a tiny bit of information, but every bit
213    makes cracking the keys easier.
214
215Instead of a message you can also call :py:func:`rsa.sign` and
216:py:func:`rsa.verify` with a :py:class:`file`-like object. If the
217message object has a ``read(int)`` method it is assumed to be a file.
218In that case the file is hashed in 1024-byte blocks at the time.
219
220    >>> with open('somefile', 'rb') as msgfile:
221    ...     signature = rsa.sign(msgfile, privkey, 'SHA-1')
222
223    >>> with open('somefile', 'rb') as msgfile:
224    ...     rsa.verify(msgfile, signature, pubkey)
225
226
227.. _bigfiles:
228
229Working with big files
230----------------------
231
232RSA can only encrypt messages that are smaller than the key. A couple
233of bytes are lost on random padding, and the rest is available for the
234message itself. For example, a 512-bit key can encode a 53-byte
235message (512 bit = 64 bytes, 11 bytes are used for random padding and
236other stuff).
237
238How it usually works
239++++++++++++++++++++
240
241The most common way to use RSA with larger files uses a block cypher
242like AES or DES3 to encrypt the file with a random key, then encrypt
243the random key with RSA. You would send the encrypted file along with
244the encrypted key to the recipient. The complete flow is:
245
246#. Generate a random key
247
248    >>> import rsa.randnum
249    >>> aes_key = rsa.randnum.read_random_bits(128)
250
251#. Use that key to encrypt the file with AES.
252#. :py:func:`Encrypt <rsa.encrypt>` the AES key with RSA
253
254    >>> encrypted_aes_key = rsa.encrypt(aes_key, public_rsa_key)
255
256#. Send the encrypted file together with ``encrypted_aes_key``
257#. The recipient now reverses this process to obtain the encrypted
258   file.
259
260.. note::
261
262    The Python-RSA module does not contain functionality to do the AES
263    encryption for you.
264
265Only using Python-RSA: the VARBLOCK format
266++++++++++++++++++++++++++++++++++++++++++
267
268.. warning::
269
270    The VARBLOCK format is NOT recommended for general use, has been deprecated since
271    Python-RSA 3.4, and has been removed in version 4.0. It's vulnerable to a
272    number of attacks:
273
274    1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor
275       uses MACs to verify messages before decrypting public key encrypted messages.
276
277    2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA)
278       and has no method for chaining, so block reordering is possible.
279
280    See `issue #19 on GitHub`_ for more information.
281
282.. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption
283.. _issue #19 on GitHub: https://github.com/sybrenstuvel/python-rsa/issues/13
284
285As of Python-RSA version 4.0, the VARBLOCK format has been removed from the
286library. For now, this section is kept here to document the issues with that
287format, and ensure we don't do something like that again.
288