Metadata-Version: 1.2
Name: hc-passphrase
Version: 1.2.1
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.2.1.tar.gz
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
        
        Generate using the verbose mode
        '''''''''''''''''''''''''''''''
        
        ::
        
            :~$ passphrase -v
            Passphrase v1.1.3
            by HacKan (https://hackan.net) FOSS under GNU GPL v3.0 or newer
            Using 77 bits of entropy for calculations (if any). The minimum recommended is 77
            Generating a passphrase of 6 words and 0 numbers using internal wordlist
            The entropy of this passphrase is 77.55 bits
            porridge browse undertone credibly underline gullible
            :~$ passphrase -v -p
            Passphrase v1.1.3
            by HacKan (https://hackan.net) FOSS under GNU GPL v3.0 or newer
            Using 77 bits of entropy for calculations (if any). The minimum recommended is 77
            Generating password of 12 characters long using uppercase characters, lowercase characters, digits, punctuation characters
            The entropy of this password is 78.66 bits
            ZJN(Lvy{D'9H
        
        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
