0

ive got an user table from an old php application where users have unsalted md5 hashes as password and because im migrating the app to django, im trying to put all users in auth_user table.

referring to this post, it is possible to store passwords as md5 hashes without salt. but that doesnt work for me? (python/2.7.6,django/1.6.1)

like e.g. for an user having password "changeme" i assume it should be in the format md5$$4cb9c8a8048fd02294477fcb1a41191a or am i missing something?

EDIT: in settings.py ive got:

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
    'django.contrib.auth.hashers.CryptPasswordHasher',
)

im using login_required decorator in views.py if somehow related:

@login_required
def index(request):
    logger.debug('index accessed from %s by %s' % (request.META.get('REMOTE_ADDR'), request.user.username) )
    member = members.objects.get(nickname=request.user.username)
    context = {'request': request, 'member': member}
    return render(request, 'voip/index.html', context)

and following urls.py:

url(r'^login/$', 'django.contrib.auth.views.login', {
  'template_name': 'voip/login.html'
}),
url(r'^logout/$', 'django.contrib.auth.views.logout_then_login', {
  #'template_name': 'voip/logout.html'
}),

this works as long as in settings.py AUTHENTICATION_BACKENDS looks like this:

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'django_auth_ldap.backend.LDAPBackend',
)

as soon as i comment out django_auth_ldap its not working. but if i then copy the pbkdf2 hash from initially installed superuser (ive set pw changeme for debugging) to my own user in auth_user table, i may log in with password "changeme"...

Community
  • 1
  • 1
Christoph Lösch
  • 645
  • 7
  • 22

3 Answers3

2

From what I can see in Django 1.6.1 source code you cannot use MD5PasswordHasher with an empty salt: https://github.com/django/django/blob/1.6.1/django/contrib/auth/hashers.py#L397.

But there is UnsaltedMD5PasswordHasher which might work for you.

EDIT: The answer you mentioned was written 4 years ago when Django 1.2 ruled the market. I've checked its password hashing code and it didn't have any assertions there, that's why MD5 hasher worked with empty salts back then.

Community
  • 1
  • 1
Tomasz Zieliński
  • 16,136
  • 7
  • 59
  • 83
1

I have two suggestions for your problem.

First, please check PASSWORD_HASHERS in settings.py. Django is able to upgrade passwords from older algorithms, but only if they are available in your configuration. Read more at the django docs.

At least you need the MD5PasswordHasher activated:

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
)

Second, if you've done that already you may try to simply store the old MD5 passwords without leading md5$$. That's also supported as a fallback. Django will recognize a 32 digit hexadecimal number as MD5 hash. This is the relevant code block from the django source code:

# Ancient versions of Django created plain MD5 passwords and accepted
# MD5 passwords with an empty salt.
if ((len(encoded) == 32 and '$' not in encoded) or
        (len(encoded) == 37 and encoded.startswith('md5$$'))):
    algorithm = 'unsalted_md5'

Hope this helps!

timo.rieber
  • 3,727
  • 3
  • 32
  • 47
  • thanks for pointing that out, tried with and without `md5$$` but doesnt work. ive edited my post with my password_hashers setting. since i dont find much on the web regarding such a problem, i guess even more its some problem on my side only, but where could i dig into to get to some point where something could fail on that matter? cause i dont see any error or similar, simply cant authenticate... – Christoph Lösch Sep 15 '14 at 23:42
-1

You can customize the authentication process, or even write your custom authentication backend. This topic is covered in official documentation:

https://docs.djangoproject.com/en/1.6/topics/auth/customizing/

Ihor Pomaranskyy
  • 5,437
  • 34
  • 37
  • well, i know about that and thought about writing a custom backend but then i have read and noticed, django automatically updates passwords using new hasher. so i just need to know how to store user's old md5 hashes in table `auth_user` to write them once and let django do its job. i've got already every other information needed, just that the authentication fails and im not sure how to store the md5 hashes correctly. – Christoph Lösch Sep 14 '14 at 04:05