Importing users - salted sha1

135 views
Skip to first unread message

Dave

unread,
Dec 2, 2009, 7:18:57 PM12/2/09
to Django users
I have a website with about 90 users that I'm trying to import into
Django. Right now, the users have a password with a salt and a hash,
so I tried (with a sample user) to format the password how Django
likes them. I did sha1$salt$hash and I wasn't able to log into admin
with that user (I made that user a superuser, staff, and active). I'm
using Django's auth authentication system. Has anyone run into this
before? Do I have to do something else to get this to work?

Thanks in advance!

Bill Freeman

unread,
Dec 3, 2009, 11:06:59 AM12/3/09
to django...@googlegroups.com
Do you have access to the password checking code for the source system?
It's fine to say that you have an SHA1 hash, but even if that's true, there
are many choices for how to represent the digest, and how to apply the
salt.

If you have access to the code, you might insert print statements to see
what various intermediate values you see. If it's just a case of representing
the hash (or salt) as an integer versus a hexadecimal string, for example,
then you have a prayer of converting. But if one applies the salt to the
beginning of the message, and the other to the end, or to both, or embeds
it, or one squashes the password to radix 50 or some such and the other
doesn't, or a number of other possibilities, you are out of luck making it
work with the default auth framework.

You could implement an additional password type in Django, using the old
site's algorithm, and calling it something other than sha1 (the key before
the first '$').
> --
>
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To post to this group, send email to django...@googlegroups.com.
> To unsubscribe from this group, send email to django-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/django-users?hl=en.
>
>
>

Dave

unread,
Dec 3, 2009, 12:10:39 PM12/3/09
to Django users
Thanks, I didn't realize there was another wrinkle in this problem. I
thought all SHA1 was the same.

I'm not sure if I have access to the code -- the site was a Ruby on
Rails site before. I followed a tutorial (http://www.aidanf.net/
rails_user_authentication_tutorial) to create the authentication
system. Here are some relevant (I think?) code snippets (from the user
model):

require 'digest/sha1'

def password=(pass)
@password=pass
self.salt = User.random_string(10) if !self.salt?
self.hashed_password = User.encrypt(@password, self.salt)
end

def self.encrypt(pass, salt)
Digest::SHA1.hexdigest(pass+salt)
end

def self.authenticate(login, pass)
u=find(:first, :conditions=>["login = ?", login])
return nil if u.nil?
return u if User.encrypt(pass, u.salt)==u.hashed_password
nil
end

If I wanted to recreate that system in django to replace the sha1$
part of the password field, would I basically need to port this code
to django?

Thanks again for your help!

Bill Freeman

unread,
Dec 3, 2009, 3:32:36 PM12/3/09
to django...@googlegroups.com
IANARP (I am not a ruby programmer), but:

If you look in django.contrib.auth.models.get_hexdigest() (about line 18),
you will see that django forms the digest on the sequence of the salt,
followed by the password the user types (raw_password).

Judging from the apperance of "self.encrypt(pass+salt)", below, ruby was
calculating the digest on the raw password followed by the salt. These are
going to give different answers, even if the salt, raw password, and sha1
algorithms are the same. (I expect the sha1s to be the same, returning 40
hexidecimal digits as a string, though the letters could be upper case in one
and lower case in the other.)

The easiest approach, if you can't demand that the users do a password
reset, would be to make yourself a custom version of that file where
get_hexdigest() accepts an additional encoding type, say 'rubysha1',
for which is combines the raw password and salt in the ruby order (and
possibly applies upper() or lower() to the result, if necessary).

Dave

unread,
Dec 4, 2009, 4:59:49 PM12/4/09
to Django users
THANK YOU!! (sorry, just a little excited).

Yes, that worked perfectly. I edited my .get_hexdigest() by simply
copying the sha1 encryption "if" statement, changed "sha1" to
"ruby" (and did the same in my password field). Then I flipped salt
and raw_password to match how it was done in my previous
authentication script. Worked like a charm! Thanks again!
Reply all
Reply to author
Forward
0 new messages