Skip to content

Instantly share code, notes, and snippets.

@juanriaza
Created February 2, 2013 22:58
Show Gist options
  • Save juanriaza/4699629 to your computer and use it in GitHub Desktop.
Save juanriaza/4699629 to your computer and use it in GitHub Desktop.
import base64
import hashlib
from django.contrib.auth.hashers import BasePasswordHasher, mask_hash
from django.utils.crypto import constant_time_compare
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy as _
class SymfonyPasswordHasher(BasePasswordHasher):
algorithm = 'symf'
iterations = 5000
digest = hashlib.sha512
def encode(self, password, salt, iterations=None):
assert password
assert salt and '$' not in salt
if not iterations:
iterations = self.iterations
password = password.encode('utf-8')
salted = '%s{%s}' % (password, salt)
salted = salted.encode('utf-8')
hash = self.digest(salted).digest()
for i in range(iterations - 1):
hash = self.digest('%s%s' % (hash, salted)).digest()
hash = base64.b64encode(hash) # .decode('ascii').strip()
return '%s$%d$%s$%s' % (self.algorithm, iterations, salt, hash)
def verify(self, password, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
assert algorithm == self.algorithm
encoded_2 = self.encode(password, salt, int(iterations))
return constant_time_compare(encoded, encoded_2)
def migrate(self, enc_password, salt):
return '%s$%d$%s$%s' % (self.algorithm, self.iterations, salt, enc_password)
def safe_summary(self, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
assert algorithm == self.algorithm
return SortedDict([
(_('algorithm'), algorithm),
(_('iterations'), iterations),
(_('salt'), mask_hash(salt)),
(_('hash'), mask_hash(hash)),
])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment