Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 1 | :mod:`crypt` --- Function to check Unix passwords |
| 2 | ================================================= |
| 3 | |
| 4 | .. module:: crypt |
| 5 | :platform: Unix |
| 6 | :synopsis: The crypt() function used to check Unix passwords. |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 7 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 8 | .. moduleauthor:: Steven D. Majewski <sdm7g@virginia.edu> |
| 9 | .. sectionauthor:: Steven D. Majewski <sdm7g@virginia.edu> |
| 10 | .. sectionauthor:: Peter Funk <pf@artcom-gmbh.de> |
| 11 | |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 12 | **Source code:** :source:`Lib/crypt.py` |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 13 | |
| 14 | .. index:: |
| 15 | single: crypt(3) |
| 16 | pair: cipher; DES |
| 17 | |
Terry Jan Reedy | fa089b9 | 2016-06-11 15:02:54 -0400 | [diff] [blame] | 18 | -------------- |
| 19 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 20 | This module implements an interface to the :manpage:`crypt(3)` routine, which is |
| 21 | a one-way hash function based upon a modified DES algorithm; see the Unix man |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 22 | page for further details. Possible uses include storing hashed passwords |
| 23 | so you can check passwords without storing the actual password, or attempting |
| 24 | to crack Unix passwords with a dictionary. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 25 | |
| 26 | .. index:: single: crypt(3) |
| 27 | |
| 28 | Notice that the behavior of this module depends on the actual implementation of |
| 29 | the :manpage:`crypt(3)` routine in the running system. Therefore, any |
| 30 | extensions available on the current implementation will also be available on |
| 31 | this module. |
| 32 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 33 | Hashing Methods |
| 34 | --------------- |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 35 | |
Éric Araujo | f215631 | 2011-05-29 03:27:48 +0200 | [diff] [blame] | 36 | .. versionadded:: 3.3 |
| 37 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 38 | The :mod:`crypt` module defines the list of hashing methods (not all methods |
| 39 | are available on all platforms): |
| 40 | |
| 41 | .. data:: METHOD_SHA512 |
| 42 | |
| 43 | A Modular Crypt Format method with 16 character salt and 86 character |
Serhiy Storchaka | eab3ff7 | 2017-10-24 19:36:17 +0300 | [diff] [blame] | 44 | hash based on the SHA-512 hash function. This is the strongest method. |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 45 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 46 | .. data:: METHOD_SHA256 |
| 47 | |
| 48 | Another Modular Crypt Format method with 16 character salt and 43 |
Serhiy Storchaka | eab3ff7 | 2017-10-24 19:36:17 +0300 | [diff] [blame] | 49 | character hash based on the SHA-256 hash function. |
| 50 | |
| 51 | .. data:: METHOD_BLOWFISH |
| 52 | |
| 53 | Another Modular Crypt Format method with 22 character salt and 31 |
| 54 | character hash based on the Blowfish cipher. |
| 55 | |
| 56 | .. versionadded:: 3.7 |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 57 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 58 | .. data:: METHOD_MD5 |
| 59 | |
| 60 | Another Modular Crypt Format method with 8 character salt and 22 |
Serhiy Storchaka | eab3ff7 | 2017-10-24 19:36:17 +0300 | [diff] [blame] | 61 | character hash based on the MD5 hash function. |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 62 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 63 | .. data:: METHOD_CRYPT |
| 64 | |
| 65 | The traditional method with a 2 character salt and 13 characters of |
| 66 | hash. This is the weakest method. |
| 67 | |
Brett Cannon | daa5799 | 2011-02-22 21:48:06 +0000 | [diff] [blame] | 68 | |
| 69 | Module Attributes |
| 70 | ----------------- |
| 71 | |
Éric Araujo | f215631 | 2011-05-29 03:27:48 +0200 | [diff] [blame] | 72 | .. versionadded:: 3.3 |
Brett Cannon | daa5799 | 2011-02-22 21:48:06 +0000 | [diff] [blame] | 73 | |
| 74 | .. attribute:: methods |
| 75 | |
| 76 | A list of available password hashing algorithms, as |
| 77 | ``crypt.METHOD_*`` objects. This list is sorted from strongest to |
Victor Stinner | 6661d88 | 2015-10-02 23:00:39 +0200 | [diff] [blame] | 78 | weakest. |
Brett Cannon | daa5799 | 2011-02-22 21:48:06 +0000 | [diff] [blame] | 79 | |
Brett Cannon | daa5799 | 2011-02-22 21:48:06 +0000 | [diff] [blame] | 80 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 81 | Module Functions |
| 82 | ---------------- |
| 83 | |
| 84 | The :mod:`crypt` module defines the following functions: |
| 85 | |
| 86 | .. function:: crypt(word, salt=None) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 87 | |
| 88 | *word* will usually be a user's password as typed at a prompt or in a graphical |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 89 | interface. The optional *salt* is either a string as returned from |
| 90 | :func:`mksalt`, one of the ``crypt.METHOD_*`` values (though not all |
| 91 | may be available on all platforms), or a full encrypted password |
| 92 | including salt, as returned by this function. If *salt* is not |
| 93 | provided, the strongest method will be used (as returned by |
| 94 | :func:`methods`. |
| 95 | |
| 96 | Checking a password is usually done by passing the plain-text password |
| 97 | as *word* and the full results of a previous :func:`crypt` call, |
| 98 | which should be the same as the results of this call. |
| 99 | |
| 100 | *salt* (either a random 2 or 16 character string, possibly prefixed with |
| 101 | ``$digit$`` to indicate the method) which will be used to perturb the |
| 102 | encryption algorithm. The characters in *salt* must be in the set |
| 103 | ``[./a-zA-Z0-9]``, with the exception of Modular Crypt Format which |
| 104 | prefixes a ``$digit$``. |
| 105 | |
| 106 | Returns the hashed password as a string, which will be composed of |
| 107 | characters from the same alphabet as the salt. |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 108 | |
| 109 | .. index:: single: crypt(3) |
| 110 | |
| 111 | Since a few :manpage:`crypt(3)` extensions allow different values, with |
| 112 | different sizes in the *salt*, it is recommended to use the full crypted |
| 113 | password as salt when checking for a password. |
| 114 | |
Éric Araujo | f215631 | 2011-05-29 03:27:48 +0200 | [diff] [blame] | 115 | .. versionchanged:: 3.3 |
| 116 | Accept ``crypt.METHOD_*`` values in addition to strings for *salt*. |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 117 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 118 | |
Serhiy Storchaka | cede8c9 | 2017-11-16 13:22:51 +0200 | [diff] [blame] | 119 | .. function:: mksalt(method=None, *, rounds=None) |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 120 | |
| 121 | Return a randomly generated salt of the specified method. If no |
| 122 | *method* is given, the strongest method available as returned by |
| 123 | :func:`methods` is used. |
| 124 | |
Serhiy Storchaka | eab3ff7 | 2017-10-24 19:36:17 +0300 | [diff] [blame] | 125 | The return value is a string suitable for passing as the *salt* argument |
| 126 | to :func:`crypt`. |
| 127 | |
Serhiy Storchaka | cede8c9 | 2017-11-16 13:22:51 +0200 | [diff] [blame] | 128 | *rounds* specifies the number of rounds for ``METHOD_SHA256``, |
| 129 | ``METHOD_SHA512`` and ``METHOD_BLOWFISH``. |
| 130 | For ``METHOD_SHA256`` and ``METHOD_SHA512`` it must be an integer between |
| 131 | ``1000`` and ``999_999_999``, the default is ``5000``. For |
| 132 | ``METHOD_BLOWFISH`` it must be a power of two between ``16`` (2\ :sup:`4`) |
| 133 | and ``2_147_483_648`` (2\ :sup:`31`), the default is ``4096`` |
| 134 | (2\ :sup:`12`). |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 135 | |
Éric Araujo | f215631 | 2011-05-29 03:27:48 +0200 | [diff] [blame] | 136 | .. versionadded:: 3.3 |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 137 | |
Serhiy Storchaka | eab3ff7 | 2017-10-24 19:36:17 +0300 | [diff] [blame] | 138 | .. versionchanged:: 3.7 |
Serhiy Storchaka | cede8c9 | 2017-11-16 13:22:51 +0200 | [diff] [blame] | 139 | Added the *rounds* parameter. |
Serhiy Storchaka | eab3ff7 | 2017-10-24 19:36:17 +0300 | [diff] [blame] | 140 | |
| 141 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 142 | Examples |
| 143 | -------- |
| 144 | |
Nick Coghlan | 74cca70 | 2012-09-28 18:50:38 +0530 | [diff] [blame] | 145 | A simple example illustrating typical use (a constant-time comparison |
| 146 | operation is needed to limit exposure to timing attacks. |
| 147 | :func:`hmac.compare_digest` is suitable for this purpose):: |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 148 | |
Éric Araujo | bc57789 | 2011-05-29 03:24:45 +0200 | [diff] [blame] | 149 | import pwd |
| 150 | import crypt |
| 151 | import getpass |
Nick Coghlan | 74cca70 | 2012-09-28 18:50:38 +0530 | [diff] [blame] | 152 | from hmac import compare_digest as compare_hash |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 153 | |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 154 | def login(): |
Éric Araujo | bc57789 | 2011-05-29 03:24:45 +0200 | [diff] [blame] | 155 | username = input('Python login: ') |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 156 | cryptedpasswd = pwd.getpwnam(username)[1] |
| 157 | if cryptedpasswd: |
Georg Brandl | 48310cd | 2009-01-03 21:18:54 +0000 | [diff] [blame] | 158 | if cryptedpasswd == 'x' or cryptedpasswd == '*': |
Éric Araujo | bc57789 | 2011-05-29 03:24:45 +0200 | [diff] [blame] | 159 | raise ValueError('no support for shadow passwords') |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 160 | cleartext = getpass.getpass() |
Nick Coghlan | 74cca70 | 2012-09-28 18:50:38 +0530 | [diff] [blame] | 161 | return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd) |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 162 | else: |
Éric Araujo | bc57789 | 2011-05-29 03:24:45 +0200 | [diff] [blame] | 163 | return True |
Georg Brandl | 116aa62 | 2007-08-15 14:28:22 +0000 | [diff] [blame] | 164 | |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 165 | To generate a hash of a password using the strongest available method and |
| 166 | check it against the original:: |
| 167 | |
| 168 | import crypt |
Nick Coghlan | 74cca70 | 2012-09-28 18:50:38 +0530 | [diff] [blame] | 169 | from hmac import compare_digest as compare_hash |
Sean Reifscheider | e2dfefb | 2011-02-22 10:55:44 +0000 | [diff] [blame] | 170 | |
| 171 | hashed = crypt.crypt(plaintext) |
Nick Coghlan | 74cca70 | 2012-09-28 18:50:38 +0530 | [diff] [blame] | 172 | if not compare_hash(hashed, crypt.crypt(plaintext, hashed)): |
Serhiy Storchaka | dba9039 | 2016-05-10 12:01:23 +0300 | [diff] [blame] | 173 | raise ValueError("hashed version doesn't validate against original") |