Metadata-Version: 1.2
Name: hc-passphrase
Version: 1.1.2
Summary: Generates cryptographically secure passphrases and passwords
Home-page: http://github.com/hackancuba/passphrase-py
Author: HacKan
Author-email: hackan@gmail.com
License: GNU GPL 3.0+
Download-URL: https://github.com/HacKanCuBa/passphrase-py/archive/v1.1.2.tar.gz
Description-Content-Type: UNKNOWN
Description: |GitHub license| |PyPI pyversions| |PyPI version| |GitHub release|
        |GitHub version| |Updates| |Build Status|
        
        Passphrase
        ==========
        
        **Passphrase** is a tool to generate **cryptographically secure**
        passphrases and passwords. A passphrase is a list of words usually
        separated by a blank space. This tool acts like a
        `diceware <http://world.std.com/~reinhold/diceware.html>`__ generator
        (more about this in `EFF's website <https://www.eff.org/es/dice>`__).
        
        Its security is based on Python's
        `os.urandom <https://docs.python.org/3/library/os.html#os.urandom>`__ to
        get cryptographically secure random bits to make an integer number. It
        also makes use of the `EFF's Large
        Wordlist <https://www.eff.org/es/document/passphrase-wordlists>`__ as
        words reference for passphrases.
        
        **Who is this tool for**: **Passphrase** is a library and a CLI tool,
        thus its intended audience are developers and advanced users that love
        to use the terminal :)
        
        A secure passphrase must be of at least 6 words, but 7 is better, and
        maybe you can add a random number to the list. If you need a password,
        make it bigger than 8 characters (`NIST's latest
        recommendation <https://nakedsecurity.sophos.com/2016/08/18/nists-new-password-rules-what-you-need-to-know/>`__),
        and prefer more than 12 (I recommend 16 or more). Passwords are
        comprised of digits, upper and lowercase letters and punctuation symbols
        - more specifically: ``ascii_lowercase``, ``ascii_uppercase``,
        ``digits`` and ``punctuation`` from
        `Lib/string <https://docs.python.org/3.6/library/string.html#string-constants>`__
        -.
        
        Those settings mentioned are specifically for the EFF's Large Wordlist.
        If you specify a different wordlist, the minimum amount of words for a
        passphrase to be secure changes: for shorter lists, the amount
        increases. The minimum secure amount of words (for a passphrase) or
        characters (for a password) are calculated by **Passphrase** and a
        warning is shown if the chosen number is too low (when used as a
        script), by calculating the list's entropy.
        
        **Important note**: the quality and security of generated passphrases
        rely on:
        
        -  the `OS-specific randomness
           source <https://docs.python.org/3/library/os.html#os.urandom>`__, and
        -  the quality of the wordlist.
        
        If you are not sure which wordlist to use, just use the one provided by
        **Passphrase** (it is used by default when running as a script) or one
        of the EFF's wordlists (check at about the middle of `this blog
        post <https://www.eff.org/es/dice>`__).
        
        Requirements
        ------------
        
        -  **Python 3.5+**.
        
        How to use it
        -------------
        
        | **Passphrase** can be used as a *package* in other apps, or as a
          *stand-alone script*.
        | Start by downloading the files, preferrably fom the `latest
          release <https://github.com/HacKanCuBa/passphrase-py/releases/latest>`__
          - releases are always signed -.
        
        You can also use *`pip <https://pypi.python.org/pypi/hc-passphrase>`__*
        but I discourage it, given that there's no cryptographic verification of
        signatures nor hashes at all.
        
        As a package
        ~~~~~~~~~~~~
        
        Check the `developers
        guide <https://github.com/HacKanCuBa/passphrase-py/blob/master/DEVELOPERS.md>`__.
        
        As a script
        ~~~~~~~~~~~
        
        Once downloaded and verified, you can install it with
        ``setup.py install`` or ``make package-install`` but I recommend you do
        ``make install`` for system-wide installation or ``make altinstall`` for
        user-wide installation, as it will create a single executable zip file
        plus install the man page.
        
        To uninstall, run respectively ``make package-uninstall``,
        ``make uninstall`` or ``make altuninstall``.
        
        Another option is to run ``pip install --user hc-passphrase`` (for
        user-wide installation) or ``pip install hc-passphrase`` (for
        system-wide installation), but I advise against this way given that pip
        doesn't do any cryptographic verification of signatures nor hashes at
        all.
        
        Examples of use
        ^^^^^^^^^^^^^^^
        
        Check the `man
        page <https://github.com/HacKanCuBa/passphrase-py/blob/master/man/passphrase.md>`__
        for more information.
        
        Generally, you should rely on **Passphrase**'s entropy calculation
        instead of fixing a desired amount, unless you specifically need some
        length/word amount. The default entropy is 77 bits, and using over 128
        bits is a wiser choice on the long term.
        
        Generate a passphrase of 6 words (default settings)
        '''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase
            trophy affiliate clobber vivacious aspect thickness
        
        Generate a passphrase of 128 bits of entropy
        ''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -e 128
            shorty collie prison reopen barge morally flavoring shifter scarcity perfume
        
        Generate a passphrase of 6 words and a number (minimum recommended)
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -w 6 -n 1
            jasmine identity chemo suave clerk copartner 853727
        
        Generate a passphrase of 6 words with 5 characters uppercase
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -w 6 --use-uppercase 5
            LiTmus cocoa littEr equation uNwrapped sibliNg
        
        Generate a passphrase of 6 words with 5 characters lowercase
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -w 6 --use-lowercase 5
            MOrTUARY SIesTa MAKEOVER CURABLE JET MARSHy
        
        Generate a password of 16 characters (minimum recommended)
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -p 16
            E`31nDL0^$oYu5='
        
        Generate a password of 8 alphanumeric characters only
        '''''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -p 8 --use-lowercase --use-uppercase --use-digits
            Warning: Insecure password length chosen! Should be bigger than or equal to 13
            7wmivbmR
            :~$ passphrase -p 8 --use-alphanumeric
            Warning: Insecure password length chosen! Should be bigger than or equal to 13
            ipLdqmGU
        
        Generate a secure password of lowercase characters only
        '''''''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -p --use-lowercase
            yafwodlcbfumtfsbb
            :~$ passphrase -p --use-lowercase -e 128
            fbwzekpmmridyapdouvejmlzlrjn
        
        Use an external wordlist to generate a passphrase
        '''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -i eff_short_wordlist_1_1column.txt
            wimp broke dash pasta zebra viral outer clasp
            :~$ passphrase -d -i eff_short_wordlist_1.txt 
            mouse trend coach stain shut rhyme baggy scale
        
        Save the output to a file
        '''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -o pass.txt
            :~$ passphrase > pass.txt
        
        Generate a passphrase and use it with GPG
        '''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ sha256sum somefile.txt
            589ed823e9a84c56feb95ac58e7cf384626b9cbf4fda2a907bc36e103de1bad2  somefile.txt
            :~$ passphrase --no-newline -o pass.txt | gpg --symmetric --batch --passphrase-fd 0 somefile.txt
            :~$ cat pass.txt | gpg --decrypt --batch --passphrase-fd 0 somefile.txt.gpg | sha256sum -
            gpg: AES256 encrypted data
            gpg: encrypted with 1 passphrase
            589ed823e9a84c56feb95ac58e7cf384626b9cbf4fda2a907bc36e103de1bad2  -
        
        Generate a passphrase avoiding `shoulder surfing <https://en.wikipedia.org/wiki/Shoulder_surfing_(computer_security)>`__
        ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -m -o pass.txt
        
        Is this really secure?
        ----------------------
        
        | First of all, we will say that a password or passphrase generator
          algorithm is secure if its output is *trully* random. To achieve that,
          **Passphrase** relies entirely on ``os.urandom``, which always
          provides an interface to the OS's cryptographically secure random
          generator. The whole program is quite big, but most of it is just the
          menues and the word list.
        | The generator algorithms are very short and simple, they are in
          `passphrase.passphrase <https://github.com/HacKanCuBa/passphrase-py/blob/master/passphrase/passphrase.py>`__:
          ``Passphrase::generate()`` and ``Passphrase::generate_password()``.
          The lower level functions are in
          `passphrase.random <https://github.com/HacKanCuBa/passphrase-py/blob/master/passphrase/random.py>`__,
          which directly uses ``os.urandom``; higher level functions are in
          `passphrase.secrets <https://github.com/HacKanCuBa/passphrase-py/blob/master/passphrase/secrets.py>`__,
          that provides a convenient interface to those low level functions, so
          that implementation errors are avoided.
        
        | The whole magic is done by ``passphrase.secrets.randbelow()``, that
          returns a random natural number lower than the given value, that is
          then used as index for the word or character list by
          ``passphrase.secrets.randchoice()``, function used by the generators.
        | Both ``randbelow()`` and ``randint()`` where copyied from Python's
          Lib/random, but trimmed down so that they don't allow anything fishy.
          This also makes **Passphrase** independent from unnecessary libraries
          and potential external vulnerabilities.
        
        The algorithms are very straight forward, easy to understand and verify.
        *Boring crypto is the best crypto*.
        
        Attack surface
        ~~~~~~~~~~~~~~
        
        Let's analyze some possible attack scenarios and its mitigations. If you
        want to add something or you see a mistake, please write an
        `issue <https://github.com/HacKanCuBa/passphrase-py/issues>`__.
        
        Attacker is root
        ^^^^^^^^^^^^^^^^
        
        TL;DR: **game over**.
        
        An attacker that is *root* can do whatever it wants, so it's out of the
        scope of this analysis.
        
        Attacker can modify source code or wordlist
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
        If it can modify the source code somehow, or the default
        `wordlist <https://github.com/HacKanCuBa/passphrase-py/blob/master/passphrase/wordlist.py>`__,
        it's also game over since a software that succesfully checks itself
        doesn't exist yet. However, it could be mitigated by placing the files
        under the ownership of some privileged user (*root*).
        
        Attacker can modify external libraries
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
        **Passphrase** doesn't require any external library, just Python 3 core.
        
        Attacker can perform a timing attack
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        
        | Words for passphrases and characters for passwords are randomly
          fetched from indexed lists. The process is: generate a random number,
          use it as index for the list, get the word or character. Timing -
          somehow - access time to this list would retrieve no difference from
          some number against another, so I think this scenario does not affect
          **Passphrase**, nor permits passphrase/password guessing.
        | However, it is possible to somehow force the list into certain memory
          pages and time cache-miss, and try to guess the word gotten from the
          list. It could be an over complicated attack, yet it does exist.
        
        Timings
        -------
        
        I realize at some point that the library was taking waaay longer to work
        than before (I solved it in
        `2c0eb8b <https://github.com/HacKanCuBa/passphrase-py/commit/2c0eb8bb8057f1c9437dba85a2df198a6f04c5ac>`__),
        so I decided to measure each version runtime from now on. So here's the
        runtime table for each tag:
        
        +-----------------+----------------+--------------------+-----------------------------------+
        | Version (tag)   | Runtime (ms)   | Relative Runtime   | Runtime Change Between Versions   |
        +=================+================+====================+===================================+
        | v0.2.3          | 43.1           | 1.00               | +0%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.2.3-1        | 41.2           | 0.96               | -4%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.3.0          | 39.1           | 0.91               | -5%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.4.1          | 107            | 2.48               | +174%                             |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.4.2          | 105            | 2.43               | -2%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.4.4          | 105            | 2.43               | +0%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.4.5          | 30.7           | 0.71               | -71%                              |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.4.7          | 30.6           | 0.71               | -0%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.4.8          | 35.6           | 0.83               | +16%                              |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.5.0          | 35.6           | 0.83               | +0%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v0.5.1          | 37.5           | 0.87               | +5%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        | v1.0.0          | 37.3           | 0.87               | -0%                               |
        +-----------------+----------------+--------------------+-----------------------------------+
        
        | You can try it yourself: download each release, unpack it and time it.
        | The command to run, depending on the release version, is:
        
        -  newer than v0.4.5, run: ``make timeit``.
        -  older than v0.4.5, run
           ``python3 -m timeit -n 100 -r 10 -s 'import os' 'os.system("python3 -m passphrase -w6 -q")'``.
        -  older than v0.4, run:
           ``python3 -m timeit -n 100 -r 10 -s 'import os' 'os.system("python3 src/passphrase.py -w6 -q")'``.
        
        License
        -------
        
        **Passphrase** is made by `HacKan <https://hackan.net>`__ under GNU GPL
        v3.0+. You are free to use, share, modify and share modifications under
        the terms of that
        `license <https://github.com/HacKanCuBa/passphrase-py/blob/master/LICENSE>`__.
        
        ::
        
            Copyright (C) 2017 HacKan (https://hackan.net)
        
            This program is free software: you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation, either version 3 of the License, or
            (at your option) any later version.
        
            This program is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
            GNU General Public License for more details.
        
            You should have received a copy of the GNU General Public License
            along with this program.  If not, see <http://www.gnu.org/licenses/>.
        
        .. |GitHub license| image:: https://img.shields.io/github/license/hackancuba/passphrase-py.svg
           :target: https://github.com/HacKanCuBa/passphrase-py/blob/master/LICENSE
        .. |PyPI pyversions| image:: https://img.shields.io/pypi/pyversions/hc-passphrase.svg
           :target: https://pypi.python.org/pypi/hc-passphrase/
        .. |PyPI version| image:: https://badge.fury.io/py/hc-passphrase.svg
           :target: https://badge.fury.io/py/hc-passphrase
        .. |GitHub release| image:: https://img.shields.io/github/release/hackancuba/passphrase-py.svg
           :target: https://github.com/hackancuba/passphrase-py/releases/
        .. |GitHub version| image:: https://badge.fury.io/gh/hackancuba%2Fpassphrase-py.svg
           :target: https://badge.fury.io/gh/hackancuba%2Fpassphrase-py
        .. |Updates| image:: https://pyup.io/repos/github/HacKanCuBa/passphrase-py/shield.svg
           :target: https://pyup.io/repos/github/HacKanCuBa/passphrase-py/
        .. |Build Status| image:: https://travis-ci.org/HacKanCuBa/passphrase-py.svg?branch=master
           :target: https://travis-ci.org/HacKanCuBa/passphrase-py
        
Keywords: cryptography passphrase password security
Platform: POSIX :: Linux
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Natural Language :: English
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Utilities
Requires-Python: >=3.5
