Changes between Initial Version and Version 1 of Ticket #37375


Ignore:
Timestamp:
Sep 28, 2026, 8:36:53 AM (79 minutes ago)
Author:
Dominic Roy
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #37375 – Description

    initial v1  
    22`hashlib.scrypt()`.
    33
    4 This means Django cannot verify an otherwise valid scrypt password hash
    5 generated by another implementation if that implementation used a different
     4As a result, Django cannot verify otherwise valid scrypt password hashes
     5generated by another implementation when that implementation uses a larger
    66derived key length.
    77
    8 This came up while working on password hash compatibility in authentik (https://goauthentik.io), where
    9 we need to be able to verify scrypt hashes imported from other systems.
     8This came up while working on password hash compatibility in authentik
     9(https://goauthentik.io), where imported scrypt hashes may come from systems
     10using different `dklen` values.
    1011
    11 For example, these two hashes use the same password, salt, N, r, and p values,
    12 but different derived key lengths:
     12Django should probably keep 64 bytes as the minimum accepted derived key
     13length rather than accepting arbitrary shorter hashes. However, hashes with a
     14larger `dklen`, for example 128 bytes, currently fail verification because
     15`verify()` always regenerates a 64-byte result.
    1316
    14 {{{
    15 scrypt$1024$salt$8$5$Xo0CV8Rk/C+B2LSvQ/MgyKJmMtW6yik2PCmVEtsZyMu01U+2KSQrCJnGfrVo4+hqUkv7Oq+AyCG9eaNdpJSn5w==
    16 scrypt$1024$salt$8$5$Xo0CV8Rk/C+B2LSvQ/MgyKJmMtW6yik2PCmVEtsZyMu01U+2KSQrCJnGfrVo4+hqUkv7Oq+AyCE=
    17 }}}
     17The derived key length can be recovered from the length of the Base64-decoded
     18digest. `verify()` could use that value when it is at least 64, while Django
     19continues generating new hashes with `dklen=64`.
    1820
    19 The first uses `dklen=64` and verifies with Django. The second uses
    20 `dklen=56` and does not.
     21If appropriate under Django's backport policy, it would also be useful to
     22include this in Django 5.2 LTS.
    2123
    22 Django's encoded scrypt format does not contain an explicit `dklen` field,
    23 but the value can be recovered from the length of the Base64-decoded digest.
    24 `verify()` could as a result derive the original key length from the stored
    25 hash and pass it to `hashlib.scrypt()`.
    26 
    27 Django could continue generating new hashes with `dklen=64`. Hashes using a
    28 different derived key length could also be considered for upgrade by
    29 `must_update()`, so they are re-encoded using Django's preferred parameters
    30 after a successful login.
    31 
    32 This would make importing existing scrypt password hashes from other
    33 implementations possible without requiring otherwise valid passwords to be
    34 reset.
    35 
    36 If this qualifies for backporting, it would also be useful to have the fix in
    37 Django 5.2 LTS.
    38 
    39 I'm happy to submit a patch if this approach is accepted!
     24I'm happy to submit a patch with tests if this approach is accepted.
Back to Top