Changes between Initial Version and Version 1 of Ticket #37375
- Timestamp:
- Sep 28, 2026, 8:36:53 AM (79 minutes ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Ticket #37375 – Description
initial v1 2 2 `hashlib.scrypt()`. 3 3 4 This means Django cannot verify an otherwise valid scrypt password hash 5 generated by another implementation if that implementation used a different4 As a result, Django cannot verify otherwise valid scrypt password hashes 5 generated by another implementation when that implementation uses a larger 6 6 derived key length. 7 7 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. 8 This came up while working on password hash compatibility in authentik 9 (https://goauthentik.io), where imported scrypt hashes may come from systems 10 using different `dklen` values. 10 11 11 For example, these two hashes use the same password, salt, N, r, and p values, 12 but different derived key lengths: 12 Django should probably keep 64 bytes as the minimum accepted derived key 13 length rather than accepting arbitrary shorter hashes. However, hashes with a 14 larger `dklen`, for example 128 bytes, currently fail verification because 15 `verify()` always regenerates a 64-byte result. 13 16 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 }}} 17 The derived key length can be recovered from the length of the Base64-decoded 18 digest. `verify()` could use that value when it is at least 64, while Django 19 continues generating new hashes with `dklen=64`. 18 20 19 The first uses `dklen=64` and verifies with Django. The second uses 20 `dklen=56` and does not.21 If appropriate under Django's backport policy, it would also be useful to 22 include this in Django 5.2 LTS. 21 23 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! 24 I'm happy to submit a patch with tests if this approach is accepted.