Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Unified Diff: third_party/gsutil/third_party/rsa/doc/usage.rst

Issue 1377933002: [catapult] - Copy Telemetry's gsutilz over to third_party. (Closed) Base URL: https://github.com/catapult-project/catapult.git@master
Patch Set: Rename to gsutil. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/gsutil/third_party/rsa/doc/usage.rst
diff --git a/third_party/gsutil/third_party/rsa/doc/usage.rst b/third_party/gsutil/third_party/rsa/doc/usage.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8a736fb476d50ce8d8e5acfdba40a86e4c4f1460
--- /dev/null
+++ b/third_party/gsutil/third_party/rsa/doc/usage.rst
@@ -0,0 +1,328 @@
+.. _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.
+
+
« no previous file with comments | « third_party/gsutil/third_party/rsa/doc/upgrading.rst ('k') | third_party/gsutil/third_party/rsa/requirements-dev-py2x.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698