| Index: tools/telemetry/third_party/gsutilz/third_party/rsa/doc/usage.rst
|
| diff --git a/tools/telemetry/third_party/gsutilz/third_party/rsa/doc/usage.rst b/tools/telemetry/third_party/gsutilz/third_party/rsa/doc/usage.rst
|
| deleted file mode 100644
|
| index 8a736fb476d50ce8d8e5acfdba40a86e4c4f1460..0000000000000000000000000000000000000000
|
| --- a/tools/telemetry/third_party/gsutilz/third_party/rsa/doc/usage.rst
|
| +++ /dev/null
|
| @@ -1,328 +0,0 @@
|
| -.. _usage:
|
| -
|
| -Usage
|
| -==================================================
|
| -
|
| -This section describes the usage of the Python-RSA module.
|
| -
|
| -Before you can use RSA you need keys. You will receive a private key
|
| -and a public key.
|
| -
|
| -.. important::
|
| -
|
| - The private key is called *private* for a reason. Never share this
|
| - key with anyone.
|
| -
|
| -The public key is used for encypting a message such that it can only
|
| -be read by the owner of the private key. As such it's also referred to
|
| -as the *encryption key*. Decrypting a message can only be done using
|
| -the private key, hence it's also called the *decryption key*.
|
| -
|
| -The private key is used for signing a message. With this signature and
|
| -the public key, the receiver can verifying that a message was signed
|
| -by the owner of the private key, and that the message was not modified
|
| -after signing.
|
| -
|
| -Generating keys
|
| ---------------------------------------------------
|
| -
|
| -You can use the :py:func:`rsa.newkeys` function to create a keypair:
|
| -
|
| - >>> (pubkey, privkey) = rsa.newkeys(512)
|
| -
|
| -Alternatively you can use :py:meth:`rsa.PrivateKey.load_pkcs1` and
|
| -:py:meth:`rsa.PublicKey.load_pkcs1` to load keys from a file:
|
| -
|
| - >>> with open('private.pem') as privatefile:
|
| - ... keydata = privatefile.read()
|
| - >>> pubkey = rsa.PrivateKey.load_pkcs1(keydata)
|
| -
|
| -
|
| -Time to generate a key
|
| -++++++++++++++++++++++++++++++++++++++++
|
| -
|
| -Generating a keypair may take a long time, depending on the number of
|
| -bits required. The number of bits determines the cryptographic
|
| -strength of the key, as well as the size of the message you can
|
| -encrypt. If you don't mind having a slightly smaller key than you
|
| -requested, you can pass ``accurate=False`` to speed up the key
|
| -generation process.
|
| -
|
| -Another way to speed up the key generation process is to use multiple
|
| -processes in parallel to speed up the key generation. Use no more than
|
| -the number of processes that your machine can run in parallel; a
|
| -dual-core machine should use ``poolsize=2``; a quad-core
|
| -hyperthreading machine can run two threads on each core, and thus can
|
| -use ``poolsize=8``.
|
| -
|
| - >>> (pubkey, privkey) = rsa.newkeys(512, poolsize=8)
|
| -
|
| -These are some average timings from my desktop machine (Linux 2.6,
|
| -2.93 GHz quad-core Intel Core i7, 16 GB RAM) using 64-bit CPython 2.7.
|
| -Since key generation is a random process, times may differ even on
|
| -similar hardware. On all tests, we used the default ``accurate=True``.
|
| -
|
| -+----------------+------------------+------------------+
|
| -| Keysize (bits) | single process | eight processes |
|
| -+================+==================+==================+
|
| -| 128 | 0.01 sec. | 0.01 sec. |
|
| -+----------------+------------------+------------------+
|
| -| 256 | 0.03 sec. | 0.02 sec. |
|
| -+----------------+------------------+------------------+
|
| -| 384 | 0.09 sec. | 0.04 sec. |
|
| -+----------------+------------------+------------------+
|
| -| 512 | 0.11 sec. | 0.07 sec. |
|
| -+----------------+------------------+------------------+
|
| -| 1024 | 0.79 sec. | 0.30 sec. |
|
| -+----------------+------------------+------------------+
|
| -| 2048 | 6.55 sec. | 1.60 sec. |
|
| -+----------------+------------------+------------------+
|
| -| 3072 | 23.4 sec. | 7.14 sec. |
|
| -+----------------+------------------+------------------+
|
| -| 4096 | 72.0 sec. | 24.4 sec. |
|
| -+----------------+------------------+------------------+
|
| -
|
| -If key generation is too slow for you, you could use OpenSSL to
|
| -generate them for you, then load them in your Python code. OpenSSL
|
| -generates a 4096-bit key in 3.5 seconds on the same machine as used
|
| -above. See :ref:`openssl` for more information.
|
| -
|
| -Key size requirements
|
| ---------------------------------------------------
|
| -
|
| -Python-RSA version 3.0 introduced PKCS#1-style random padding. This
|
| -means that 11 bytes (88 bits) of your key are no longer usable for
|
| -encryption, so keys smaller than this are unusable. The larger the
|
| -key, the higher the security.
|
| -
|
| -Creating signatures also requires a key of a certain size, depending
|
| -on the used hash method:
|
| -
|
| -+-------------+-----------------------------------+
|
| -| Hash method | Suggested minimum key size (bits) |
|
| -+=============+===================================+
|
| -| MD5 | 360 |
|
| -+-------------+-----------------------------------+
|
| -| SHA-1 | 368 |
|
| -+-------------+-----------------------------------+
|
| -| SHA-256 | 496 |
|
| -+-------------+-----------------------------------+
|
| -| SHA-384 | 624 |
|
| -+-------------+-----------------------------------+
|
| -| SHA-512 | 752 |
|
| -+-------------+-----------------------------------+
|
| -
|
| -
|
| -
|
| -Encryption and decryption
|
| ---------------------------------------------------
|
| -
|
| -To encrypt or decrypt a message, use :py:func:`rsa.encrypt` resp.
|
| -:py:func:`rsa.decrypt`. Let's say that Alice wants to send a message
|
| -that only Bob can read.
|
| -
|
| -#. Bob generates a keypair, and gives the public key to Alice. This is
|
| - done such that Alice knows for sure that the key is really Bob's
|
| - (for example by handing over a USB stick that contains the key).
|
| -
|
| - >>> (bob_pub, bob_priv) = rsa.newkeys(512)
|
| -
|
| -#. Alice writes a message
|
| -
|
| - >>> message = 'hello Bob!'
|
| -
|
| -#. Alice encrypts the message using Bob's public key, and sends the
|
| - encrypted message.
|
| -
|
| - >>> crypto = rsa.encrypt(message, bob_pub)
|
| -
|
| -#. Bob receives the message, and decrypts it with his private key.
|
| -
|
| - >>> message = rsa.decrypt(crypto, bob_priv)
|
| - >>> print message
|
| - hello Bob!
|
| -
|
| -Since Bob kept his private key *private*, Alice can be sure that he is
|
| -the only one who can read the message. Bob does *not* know for sure
|
| -that it was Alice that sent the message, since she didn't sign it.
|
| -
|
| -
|
| -RSA can only encrypt messages that are smaller than the key. A couple
|
| -of bytes are lost on random padding, and the rest is available for the
|
| -message itself. For example, a 512-bit key can encode a 53-byte
|
| -message (512 bit = 64 bytes, 11 bytes are used for random padding and
|
| -other stuff). See :ref:`bigfiles` for information on how to work with
|
| -larger files.
|
| -
|
| -Altering the encrypted information will *likely* cause a
|
| -:py:class:`rsa.pkcs1.DecryptionError`. If you want to be *sure*, use
|
| -:py:func:`rsa.sign`.
|
| -
|
| - >>> crypto = encrypt('hello', pub_key)
|
| - >>> crypto = 'X' + crypto[1:] # change the first byte
|
| - >>> decrypt(crypto, priv_key)
|
| - Traceback (most recent call last):
|
| - ...
|
| - rsa.pkcs1.DecryptionError: Decryption failed
|
| -
|
| -
|
| -.. warning::
|
| -
|
| - Never display the stack trace of a
|
| - :py:class:`rsa.pkcs1.DecryptionError` exception. It shows where
|
| - in the code the exception occurred, and thus leaks information
|
| - about the key. It’s only a tiny bit of information, but every bit
|
| - makes cracking the keys easier.
|
| -
|
| -Low-level operations
|
| -++++++++++++++++++++++++++++++
|
| -
|
| -The core RSA algorithm operates on large integers. These operations
|
| -are considered low-level and are supported by the
|
| -:py:func:`rsa.core.encrypt_int` and :py:func:`rsa.core.decrypt_int`
|
| -functions.
|
| -
|
| -Signing and verification
|
| ---------------------------------------------------
|
| -
|
| -You can create a detached signature for a message using the
|
| -:py:func:`rsa.sign` function:
|
| -
|
| - >>> (pubkey, privkey) = rsa.newkeys(512)
|
| - >>> message = 'Go left at the blue tree'
|
| - >>> signature = rsa.sign(message, privkey, 'SHA-1')
|
| -
|
| -This hashes the message using SHA-1. Other hash methods are also
|
| -possible, check the :py:func:`rsa.sign` function documentation for
|
| -details. The hash is then signed with the private key.
|
| -
|
| -In order to verify the signature, use the :py:func:`rsa.verify`
|
| -function. This function returns True if the verification is successful:
|
| -
|
| - >>> message = 'Go left at the blue tree'
|
| - >>> rsa.verify(message, signature, pubkey)
|
| - True
|
| -
|
| -Modify the message, and the signature is no longer valid and a
|
| -:py:class:`rsa.pkcs1.VerificationError` is thrown:
|
| -
|
| - >>> message = 'Go right at the blue tree'
|
| - >>> rsa.verify(message, signature, pubkey)
|
| - Traceback (most recent call last):
|
| - File "<stdin>", line 1, in <module>
|
| - File "/home/sybren/workspace/python-rsa/rsa/pkcs1.py", line 289, in verify
|
| - raise VerificationError('Verification failed')
|
| - rsa.pkcs1.VerificationError: Verification failed
|
| -
|
| -.. warning::
|
| -
|
| - Never display the stack trace of a
|
| - :py:class:`rsa.pkcs1.VerificationError` exception. It shows where
|
| - in the code the exception occurred, and thus leaks information
|
| - about the key. It's only a tiny bit of information, but every bit
|
| - makes cracking the keys easier.
|
| -
|
| -Instead of a message you can also call :py:func:`rsa.sign` and
|
| -:py:func:`rsa.verify` with a :py:class:`file`-like object. If the
|
| -message object has a ``read(int)`` method it is assumed to be a file.
|
| -In that case the file is hashed in 1024-byte blocks at the time.
|
| -
|
| - >>> with open('somefile', 'rb') as msgfile:
|
| - ... signature = rsa.sign(msgfile, privkey, 'SHA-1')
|
| -
|
| - >>> with open('somefile', 'rb') as msgfile:
|
| - ... rsa.verify(msgfile, signature, pubkey)
|
| -
|
| -
|
| -.. _bigfiles:
|
| -
|
| -Working with big files
|
| ---------------------------------------------------
|
| -
|
| -RSA can only encrypt messages that are smaller than the key. A couple
|
| -of bytes are lost on random padding, and the rest is available for the
|
| -message itself. For example, a 512-bit key can encode a 53-byte
|
| -message (512 bit = 64 bytes, 11 bytes are used for random padding and
|
| -other stuff).
|
| -
|
| -How it usually works
|
| -++++++++++++++++++++++++++++++++++++++++
|
| -
|
| -The most common way to use RSA with larger files uses a block cypher
|
| -like AES or DES3 to encrypt the file with a random key, then encrypt
|
| -the random key with RSA. You would send the encrypted file along with
|
| -the encrypted key to the recipient. The complete flow is:
|
| -
|
| -#. Generate a random key
|
| -
|
| - >>> import rsa.randnum
|
| - >>> aes_key = rsa.randnum.read_random_bits(128)
|
| -
|
| -#. Use that key to encrypt the file with AES.
|
| -#. :py:func:`Encrypt <rsa.encrypt>` the AES key with RSA
|
| -
|
| - >>> encrypted_aes_key = rsa.encrypt(aes_key, public_rsa_key)
|
| -
|
| -#. Send the encrypted file together with ``encrypted_aes_key``
|
| -#. The recipient now reverses this process to obtain the encrypted
|
| - file.
|
| -
|
| -.. note::
|
| -
|
| - The Python-RSA module does not contain functionality to do the AES
|
| - encryption for you.
|
| -
|
| -Only using Python-RSA: the VARBLOCK format
|
| -+++++++++++++++++++++++++++++++++++++++++++
|
| -
|
| -As far as we know, there is no pure-Python AES encryption. Previous
|
| -versions of Python-RSA included functionality to encrypt large files
|
| -with just RSA, and so does this version. The format has been improved,
|
| -though.
|
| -
|
| -Encrypting works as follows: the input file is split into blocks that
|
| -are just large enough to encrypt with your RSA key. Every block is
|
| -then encrypted using RSA, and the encrypted blocks are assembled into
|
| -the output file. This file format is called the :ref:`VARBLOCK
|
| -<VARBLOCK>` format.
|
| -
|
| -Decrypting works in reverse. The encrypted file is separated into
|
| -encrypted blocks. Those are decrypted, and assembled into the original
|
| -file.
|
| -
|
| -.. note::
|
| -
|
| - The file will get larger after encryption, as each encrypted block
|
| - has 8 bytes of random padding and 3 more bytes of overhead.
|
| -
|
| -Since these encryption/decryption functions are potentially called on
|
| -very large files, they use another approach. Where the regular
|
| -functions store the message in memory in its entirety, these functions
|
| -work on one block at the time. As a result, you should call them with
|
| -:py:class:`file`-like objects as the parameters.
|
| -
|
| -Before using we of course need a keypair:
|
| -
|
| ->>> import rsa
|
| ->>> (pub_key, priv_key) = rsa.newkeys(512)
|
| -
|
| -Encryption works on file handles using the
|
| -:py:func:`rsa.bigfile.encrypt_bigfile` function:
|
| -
|
| ->>> from rsa.bigfile import *
|
| ->>> with open('inputfile', 'rb') as infile, open('outputfile', 'wb') as outfile:
|
| -... encrypt_bigfile(infile, outfile, pub_key)
|
| -
|
| -As does decryption using the :py:func:`rsa.bigfile.decrypt_bigfile`
|
| -function:
|
| -
|
| ->>> from rsa.bigfile import *
|
| ->>> with open('inputfile', 'rb') as infile, open('outputfile', 'wb') as outfile:
|
| -... decrypt_bigfile(infile, outfile, priv_key)
|
| -
|
| -.. note::
|
| -
|
| - :py:func:`rsa.sign` and :py:func:`rsa.verify` work on arbitrarily
|
| - long files, so they do not have a "bigfile" equivalent.
|
| -
|
| -
|
|
|