From 8a39f254ad3edf8c22897f64822539c860a409bb Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 6 Apr 2016 15:33:26 -0400 Subject: [PATCH] Switched to a custom low-iteration Secret hasher to avoid excessive delay when retrieving many Secrets --- netbox/secrets/hashers.py | 9 +++++++++ netbox/secrets/models.py | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 netbox/secrets/hashers.py diff --git a/netbox/secrets/hashers.py b/netbox/secrets/hashers.py new file mode 100644 index 000000000..fc5066fc6 --- /dev/null +++ b/netbox/secrets/hashers.py @@ -0,0 +1,9 @@ +from django.contrib.auth.hashers import PBKDF2PasswordHasher + + +class SecretValidationHasher(PBKDF2PasswordHasher): + """ + We're using Django's stock SHA256 hasher with a low iteration count to avoid introducing excessive delay when + retrieving a large number of Secrets (the plaintext of each Secret is validated against its hash upon decryption). + """ + iterations = 1000 diff --git a/netbox/secrets/models.py b/netbox/secrets/models.py index 6bcc5995a..270f93501 100644 --- a/netbox/secrets/models.py +++ b/netbox/secrets/models.py @@ -11,6 +11,7 @@ from django.db import models from django.utils.encoding import force_bytes from dcim.models import Device +from .hashers import SecretValidationHasher def generate_master_key(): @@ -245,7 +246,7 @@ class Secret(models.Model): self.ciphertext = iv + aes.encrypt(self._pad(self.plaintext)) # Generate SHA256 using Django's built-in password hashing mechanism - self.hash = make_password(self.plaintext, hasher='pbkdf2_sha256') + self.hash = make_password(self.plaintext, hasher=SecretValidationHasher()) self.plaintext = None @@ -277,4 +278,4 @@ class Secret(models.Model): """ if not self.hash: raise Exception("Hash has not been generated for this secret.") - return check_password(plaintext, self.hash) + return check_password(plaintext, self.hash, preferred=SecretValidationHasher())