create a md5 / md5 passwd with a salt

P

Peter Woodsky

Hi list

This problem is so above me my head is swimming.

I have a forum software that recently changed the way passwords were
stored. I use a ruby script to update the user table when the user
changes the password but my script no longer works so I hope someone
here can help or point me in the right direction.

The forum now uses this format for storing passwords md5(md5(PASSWORD) .
salt) where previously it was md5(PASSWORD) which was pretty easy to
deal with.

This is what I used before:

require 'cgi'
cgi = CGI.new
require 'digest/md5'
user_pwd = hash_class.hexdigest("#{password}")
end

Like I said I hope someone has an idea or solution.

Thanks in advance,
Peter
 
A

Aaron Turner

Hi list

This problem is so above me my head is swimming.

I have a forum software that recently changed the way passwords were
stored. I use a ruby script to update the user table when the user
changes the password but my script no longer works so I hope someone
here can help or point me in the right direction.

The forum now uses this format for storing passwords md5(md5(PASSWORD) .
salt) where previously it was md5(PASSWORD) which was pretty easy to
deal with.

This is what I used before:

require 'cgi'
cgi = CGI.new
require 'digest/md5'
user_pwd = hash_class.hexdigest("#{password}")
end


user_pwd = Digest::MD5.hexdigest(Digest::MD5.hexdigest(password) + salt)

I will point out this though: for this to work, somewhere you need to
store the PLAIN TEXT salt in the DB. Usually this is done by
pre-pending the salt to the hashed pasword like this:

user_pwd = salt + Digest::MD5.hexdigest(Digest::MD5.hexdigest(password) + salt)

Or it might be stored in another field in the DB. That way when the
user logs in, you can use the salt again to test to see if the hashes
match.



--
Aaron Turner
http://synfin.net/
http://tcpreplay.synfin.net/ - Pcap editing and replay tools for Unix & Windows
They that can give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety. -- Benjamin Franklin
 
B

Brian Candler

Peter said:
The forum now uses this format for storing passwords md5(md5(PASSWORD) .
salt) where previously it was md5(PASSWORD) which was pretty easy to
deal with.

You should give an example of a password, a salt, and the expected
output. That's not any "standard" way of hashing an output that I've
seen.

Is the inner md5() function producing a binary output (16 bytes) or hex
(32 characters)? Or something else, e.g. base64 (24 characters)?

Anyway, it'll be easy enough to code if you know what you're looking
for. You can test if you're doing it right in irb.

Example: I've arbitarily chosen inner md5 is binary, outer MD5 is hex:

irb(main):001:0> require 'digest/md5'
=> true
irb(main):002:0> Digest::MD5.digest("hello")
=> "]A@*\274K*v\271q\235\221\020\027\305\222"
irb(main):003:0> Digest::MD5.digest("hello") + "mysalt"
=> "]A@*\274K*v\271q\235\221\020\027\305\222mysalt"
irb(main):004:0> Digest::MD5.hexdigest(Digest::MD5.digest("hello") +
"mysalt")
=> "263058590f9387d91f98266a832fabaf"
 
P

Peter Woodsky

Brian said:
Peter said:
The forum now uses this format for storing passwords md5(md5(PASSWORD) .
salt) where previously it was md5(PASSWORD) which was pretty easy to
deal with.

You should give an example of a password, a salt, and the expected
output. That's not any "standard" way of hashing an output that I've
seen.

Is the inner md5() function producing a binary output (16 bytes) or hex
(32 characters)? Or something else, e.g. base64 (24 characters)?

Anyway, it'll be easy enough to code if you know what you're looking
for. You can test if you're doing it right in irb.

Example: I've arbitarily chosen inner md5 is binary, outer MD5 is hex:

irb(main):001:0> require 'digest/md5'
=> true
irb(main):002:0> Digest::MD5.digest("hello")
=> "]A@*\274K*v\271q\235\221\020\027\305\222"
irb(main):003:0> Digest::MD5.digest("hello") + "mysalt"
=> "]A@*\274K*v\271q\235\221\020\027\305\222mysalt"
irb(main):004:0> Digest::MD5.hexdigest(Digest::MD5.digest("hello") +
"mysalt")
=> "263058590f9387d91f98266a832fabaf"

From the first solution given it works as it should. All that was
required was "" for the vars password and salt.

md5_w_salt = Digest::MD5.hexdigest(Digest::MD5.hexdigest("#{password}")
+ "#{row[0]}")

Thanks again!
 
B

Brian Candler

Peter said:
From the first solution given it works as it should. All that was
required was "" for the vars password and salt.

md5_w_salt = Digest::MD5.hexdigest(Digest::MD5.hexdigest("#{password}")
+ "#{row[0]}")

Glad it works. Note that if password and row[0] are Strings, you should
not need to wrap them in "#{..}" since you are just interpolating a
String into another String.
 
B

Brian Candler

Greg said:
MD5 is no longer secure:

http://www.google.com/search?q=md5+broken


There are a number of MD5 lookup dictionaries already online for a
couple years now, for example:

http://gdataonline.com/seekhash.php
http://passcracking.com/

I think you're confusing two things.

1. MD5 has been broken, in the sense that you can make two versions of a
document with the same MD5 hash

2. You can have lookup dictionaries for hashes. However the same could
be done for SHA1 or any other hash, and does not depend on (1).

But in any case:

* the OP's algorithm has a salt. If well chosen (random and long
enough), this should eliminate the dictionary attack. (It would be
better if it were a HMAC construction though)

* the OP seems to have no choice in the algorithm to use anyway

* the OP wasn't asking for security advice :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top