py-scrypt / README.rst

Full commit
Magnus Hallin 3ca091c 

 Python scrypt_ bindings

This is a set of Python_ bindings for the scrypt_ key derivation

Scrypt is useful when encrypting password as it is possible to specify
a *minimum* amount of time to use when encrypting and decrypting. If,
for example, a password takes 0.05 seconds to verify, a user won't
notice the slight delay when signing in, but doing a brute force
search of several billion passwords will take a considerable amount of
time. This is in contrast to more traditional hash functions such as
MD5 or the SHA family which can be implemented extremely fast on cheap


You can install py-scrypt from this repository if you want the latest
but possibly non-compiling version::

    $ hg clone
    $ cd py-scrypt
    $ python build

    Become superuser (or use virtualenv):
    # python install

    Run tests after install:
    $ python test

Or you can install the latest release from PyPi::

    $ pip install scrypt

If you want py-scrypt for your Python 3 environment, just run the
above commands with your Python 3 interpreter. Py-scrypt supports both
Python 2 and 3.

From version 0.6.0 (not available on PyPi yet), py-scrypt supports
PyPy as well.


Fore encryption/decryption, the library exports two functions
``encrypt`` and ``decrypt``::

    >>> import scrypt
    >>> data = scrypt.encrypt('a secret message', 'password', maxtime=0.1) # This will take at least 0.1 seconds
    >>> data[:20]
    >>> scrypt.decrypt(data, 'password', maxtime=0.1) # This will also take at least 0.1 seconds
    'a secret message'
    >>> scrypt.decrypt(data, 'password', maxtime=0.05) # scrypt won't be able to decrypt this data fast enough
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    scrypt.error: decrypting file would take too long
    >>> scrypt.decrypt(data, 'wrong password', maxtime=0.1) # scrypt will throw an exception if the password is incorrect
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    scrypt.error: password is incorrect

From these, one can make a simple password verifier using the following

    def randstr(length):
        return ''.join(chr(random.randint(0,255)) for i in range(length))

    def hash_password(password, maxtime=0.5, datalength=64):
        return scrypt.encrypt(randstr(datalength), password, maxtime=maxtime)

    def verify_password(hashed_password, guessed_password, maxtime=0.5):
            scrypt.decrypt(hashed_password, guessed_password, maxtime)
            return True
        except scrypt.error:
            return False

But, if you want output that is deterministic and constant in size,
you can use the ``hash`` function::

    >>> import scrypt
    >>> h1 = scrypt.hash('password', 'random salt')
    >>> len(h1)  # The hash will be 64 bytes by default, but is overridable.
    >>> h1[:10]
    >>> h2 = scrypt.hash('password', 'random salt')
    >>> h1 == h2 # The hash function is deterministic


Scrypt_ was created by Colin Percival and is licensed as 2-clause BSD.
Since scrypt does not normally build as a shared library, I have included
the source for the currently latest version of the library in this
repository. When a new version arrives, I will update these sources.

`Kelvin Wong`_ on Bitbucket provided changes to make the library
available on Mac OS X 10.6 and earlier, as well as changes to make the
library work more like the command-line version of scrypt by
default. Kelvin also contributed with the unit tests, lots of cross
platform testing and work on the ``hash`` function.

Burstaholic_ on Bitbucket provided the necessary changes to make
the library build on Windows.


This library is licensed under the same license as scrypt; 2-clause BSD.

.. _scrypt:
.. _Python:
.. _Burstaholic:
.. _Kelvin Wong: