From 17a83dee60364e502bd946897117d53819b6bf04 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Wed, 22 Sep 2021 10:36:52 -0700 Subject: [PATCH] settings: Choose password hashing complexity suitable for SBCs - Django 3.2 has a argon2 password hashing complexity unsuitable for single board computers. Choose parameters suitable for Olimex Lime2 boards. Tests: - In a browser, login to a user without these changes. Notice the hash parameters in sqlite3 auth_user table. Login with the changes. Notice that the hash has been updated with latest has parameters. - Login in Django 2.2 and Django 3.2. Login succeeds and hash parameters are updated. - As measured by the browser. Notice that change in login request time with and without these changes Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- plinth/hashers.py | 34 ++++++++++++++++++++++++++++++++++ plinth/settings.py | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 plinth/hashers.py diff --git a/plinth/hashers.py b/plinth/hashers.py new file mode 100644 index 000000000..6f1fdde6f --- /dev/null +++ b/plinth/hashers.py @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +""" +Custom password hashers suitable for home servers. +""" + +from django.contrib.auth.hashers import Argon2PasswordHasher + + +class Argon2PasswordHasherLowMemory(Argon2PasswordHasher): + """Argon2 password hasher that uses less CPU and RAM than Django's default. + + Derive from and override the default complexity parameters for Django. In + Django 2.2, the defaults are time: 2, memory: 512 and parallelism: 2. In + Django 3.2, the defaults are time: 2, memory: 102400, parallelism: 8. This + takes more than 3 seconds per verification on a Lime2 board. + + On a Pioneer Edition, Olimex Lime2 board, the selected parameters result in + about 200ms for password verification: + + $ python3 -m argon2 -p 2 -m 4096 + Running Argon2id 100 times with: + hash_len: 16 bytes + memory_cost: 4096 KiB + parallelism: 2 threads + time_cost: 2 iterations + + Measuring... + + 2.17e+02ms per password verification + + """ + time_cost = 2 # Iterations + memory_cost = 4096 # KiB + parallelism = 2 # Threads diff --git a/plinth/settings.py b/plinth/settings.py index 5845c3dd3..6213d74a7 100644 --- a/plinth/settings.py +++ b/plinth/settings.py @@ -131,7 +131,7 @@ MIDDLEWARE = ( ) PASSWORD_HASHERS = [ - 'django.contrib.auth.hashers.Argon2PasswordHasher', + 'plinth.hashers.Argon2PasswordHasherLowMemory', 'django.contrib.auth.hashers.PBKDF2PasswordHasher', 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',