This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: crypt function not hashing properly on Mac (uses a specific salt)
Type: security Stage:
Components: Extension Modules, macOS Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Ron Reiter, andrei.avk, christian.heimes, ned.deily, rhettinger, ronaldoussoren, serhiy.storchaka
Priority: normal Keywords:

Created on 2018-04-03 08:26 by Ron Reiter, last changed 2022-04-11 14:58 by admin.

Messages (13)
msg314866 - (view) Author: Ron Reiter (Ron Reiter) Date: 2018-04-03 08:26
import crypt

Expected result:
>>> crypt.crypt("test") == crypt.crypt("test")
False
>>> crypt.crypt("test", crypt.mksalt()) == crypt.crypt("test", crypt.mksalt())
False

Unexpected results:
>>> crypt.crypt("test", crypt.METHOD_SHA512) == crypt.crypt("test", crypt.METHOD_SHA512)
True
>>> crypt.crypt("test", crypt.mksalt(crypt.METHOD_SHA512)) == crypt.crypt("test", crypt.mksalt(crypt.METHOD_SHA512))
False
msg314867 - (view) Author: Ron Reiter (Ron Reiter) Date: 2018-04-03 08:28
import crypt

Expected result:
>>> crypt.crypt("test") == crypt.crypt("test")
False
>>> crypt.crypt("test", crypt.mksalt()) == crypt.crypt("test", crypt.mksalt())
False

Unexpected results:
>>> crypt.crypt("test", crypt.METHOD_SHA512) == crypt.crypt("test", crypt.METHOD_SHA512)
True
>>> crypt.crypt("test", crypt.mksalt(crypt.METHOD_SHA512)) == crypt.crypt("test", crypt.mksalt(crypt.METHOD_SHA512))
True
msg314868 - (view) Author: Ron Reiter (Ron Reiter) Date: 2018-04-03 08:39
You guessed it, the salt is "$6"
msg314871 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-04-03 08:54
I can't reproduce this result. Does your os.urandom() broken and return a short repeated sequence?
msg314872 - (view) Author: Ron Reiter (Ron Reiter) Date: 2018-04-03 09:47
Apparently it's a Mac issue. My crypt.methods only contains [<crypt.METHOD_CRYPT>] which is probably why this fails. It's a silent failure of some sort that is causing this.
msg314873 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2018-04-03 10:12
The crypt module is a thin wrapper around the OS' crypt(3) function. The function should return NULL for unsupported salt types. The module turns NULL into None.

What's the return value of crypt.crypt("test", crypt.METHOD_SHA512) ?
msg314874 - (view) Author: Ron Reiter (Ron Reiter) Date: 2018-04-03 10:46
Python 3.6.4 (default, Mar 22 2018, 23:35:12)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
>>> crypt.crypt("test", crypt.METHOD_SHA512)
'$6asQOJRqB1i2'
>>> crypt.crypt("test", crypt.METHOD_SHA512)
'$6asQOJRqB1i2'
msg314875 - (view) Author: Ron Reiter (Ron Reiter) Date: 2018-04-03 10:47
Also:
>>> crypt.crypt("test", "$5")
'$5yVOkTkyRzn.'
>>> crypt.crypt("test", "$6")
'$6asQOJRqB1i2'
>>> crypt.crypt("test", "$7")
'$7tSOkvDyiL6U'

So the salt is "$6"
msg314884 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2018-04-03 15:17
> What's the return value of crypt.crypt("test", crypt.METHOD_SHA512) 

This is from my Mac (10.13.3):

$ python3.6
Python 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
>>> crypt.crypt("test", crypt.METHOD_SHA512)
'$6asQOJRqB1i2'
>>> crypt.crypt("test", crypt.METHOD_SHA512)
'$6asQOJRqB1i2'
>>> crypt.crypt("test", "$5")
'$5yVOkTkyRzn.'
>>> crypt.crypt("test", "$6")
'$6asQOJRqB1i2'
>>> crypt.crypt("test", "$7")
'$7tSOkvDyiL6U'
>>> crypt.crypt("test") == crypt.crypt("test")
False
>>> crypt.crypt("test", crypt.mksalt()) == crypt.crypt("test", crypt.mksalt())
False
msg314926 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2018-04-04 06:00
$ ./bin/python3
Python 3.8.0a0 (heads/master:55966f3a0d, Apr  2 2018, 18:16:13)
[Clang 9.1.0 (clang-902.0.39.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import crypt
>>> crypt.methods
[<crypt.METHOD_CRYPT>]
msg314938 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2018-04-04 15:33
As far as I know macOS does not support different salt types at all. The manpage does mention an "extended crypt", but according to the documentation that just controls the number of DES rounds used.

In particular:

    The salt is a 9-character array consisting of an underscore, followed by 
    4 bytes of iteration count and 4 bytes of salt.  These are encoded as
    printable characters, 6 bits per character, least significant character
    first.  The values 0 to 63 are encoded as ``./0-9A-Za-z''.  This allows 
    24 bits for both count and salt.


If anything needs to change it would have to be a macOS specific patch to the _crypt extension that rejects any attempt of using algorithm selection (but that's technically a backward incompatible change as)
msg396174 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-06-20 14:48
How about adding a check to `crypt.mksalt()`:

if method and method not in methods:
    raise ValueError(f'method {method} is not supported')

If a method is supplied to `crypt.crypt()`, mksalt() is called with it as an arg, so adding this check will take care of both paths:
crypt(val, method)
crypt(val, mksalt(method))

the only remaining issue is if an (improperly generated) salt is loaded
from somewhere and used to call `crypt()`, but the check above fixes most of the issue.

I can put up a PR if this sounds good.
msg396175 - (view) Author: Andrei Kulakov (andrei.avk) * (Python triager) Date: 2021-06-20 14:54
Actually it should be:

  if method is not None and method not in methods:
    ...
History
Date User Action Args
2022-04-11 14:58:59adminsetgithub: 77394
2021-06-20 14:54:03andrei.avksetmessages: + msg396175
2021-06-20 14:48:53andrei.avksetnosy: + andrei.avk
messages: + msg396174
2021-05-25 07:01:33mark.dickinsonsetnosy: - mark.dickinson
2021-05-22 00:25:40ned.deilysetcomponents: + macOS
versions: + Python 3.11, - Python 3.6, Python 3.7, Python 3.8
2018-04-07 13:33:00Ron Reitersettype: security
2018-04-04 15:33:35ronaldoussorensetnosy: + ronaldoussoren
messages: + msg314938
2018-04-04 06:00:46ned.deilysetnosy: + ned.deily

messages: + msg314926
versions: + Python 3.7, Python 3.8
2018-04-03 15:17:36rhettingersetmessages: + msg314884
2018-04-03 10:48:23Ron Reitersettitle: crypt function not hashing properly -> crypt function not hashing properly on Mac (uses a specific salt)
2018-04-03 10:47:08Ron Reitersetmessages: + msg314875
2018-04-03 10:46:00Ron Reitersetmessages: + msg314874
2018-04-03 10:12:43christian.heimessetnosy: + christian.heimes
messages: + msg314873
2018-04-03 09:47:25Ron Reitersetmessages: + msg314872
2018-04-03 08:54:29serhiy.storchakasetnosy: + rhettinger, serhiy.storchaka, mark.dickinson
messages: + msg314871
2018-04-03 08:39:23Ron Reitersetmessages: + msg314868
2018-04-03 08:28:10Ron Reitersetmessages: + msg314867
2018-04-03 08:26:58Ron Reitercreate