Ruby sha512 password retrieval in php
(Updated due to some confusion over my question) We use this method to generate a digested_password, which is saved to our database for later lookup. When we authenticate a user to our application, this method is again ran against their input and开发者_Python百科 if the digested_password output matches the digested_password we saved in the database we authenticate them. I need to reproduce this function in PHP for another application that shares the database.
def self.hash_password( password, salt )
salted_password = password.insert 4, salt
digested_password = Digest::SHA512.hexdigest("#{salted_password}")
return digested_password
end
I really have no experience with Ruby so please forgive my lack of understanding.
Thanks!
Because you can't "retrieve" a password from a one-way hash like SHA-512, the closest we can get is being able to generate the same hash from the same password and salt. Let's look at the Ruby code:
def self.hash_password( password, salt )
salted_password = password.insert 4, salt
digested_password = Digest::SHA512.hexdigest("#{salted_password}")
return digested_password
end
The only thing a bit "weird" here is the call to the .insert
method on the password string. It's basically splicing the salt right into the password, starting at the fourth character index. Normally salts are simply concatenated with the password.
We can replicate this using substr
:
function hash_password($password, $salt) {
$salted_password = substr($password, 0, 4) . $salt . substr($password, 4);
return hash('sha512', $salted_password);
}
I'm using the now-default hash extension here, as it's pretty much the most reliable way to generate a SHA-512 hash.
Using this code, you should be able to generate identical hashes for a given identical password and salt combination. I'm not sure what the behavior would be when the password is less than five characters long.
Yup, looks like it should work:
[charles@lobotomy ~]$ irb
irb(main):001:0> require 'digest/sha2'
=> true
irb(main):002:0> def hash_password( password, salt )
irb(main):003:1> salted_password = password.insert 4, salt
irb(main):004:1> digested_password = Digest::SHA512.hexdigest("#{salted_password}")
irb(main):005:1> return digested_password
irb(main):006:1> end
=> nil
irb(main):007:0* puts hash_password('password', 'salt')
92d3efdbf51d199b0930c427b77dc8d5cf41ac58b6fab5f89cc3f32d719a8f6ffcdff6211bdd0565a6e7b09925839e5dcce1fa5abf65eca87c6a883ab0b510b9
=> nil
irb(main):018:0> exit
[charles@lobotomy ~]$
[charles@lobotomy ~]$ php -a
Interactive shell
php > function hash_password($password, $salt) {
php { $salted_password = substr($password, 0, 4) . $salt . substr($password, 4);
php { return hash('sha512', $salted_password);
php { }
php > echo hash_password('password', 'salt');
92d3efdbf51d199b0930c427b77dc8d5cf41ac58b6fab5f89cc3f32d719a8f6ffcdff6211bdd0565a6e7b09925839e5dcce1fa5abf65eca87c6a883ab0b510b9
php >
function hash_password($password, $salt)
{
$salted_password = substr_replace($password, $salt, 4, 0);
$digested_password = hash('sha512', $salted_password);
return $digested_password;
}
SHA512 is a one way hash function, meaning that you can't easily get the input for any given output.
It is possible, but very expensive, to build a rainbow table. Because this is a salted hash, it's even more difficult
I figured it out. I didn't quite understand the insert method in Ruby, and it turns out the salt is being inserted into the password at the fourth character. Here is the PHP equivalent:
$password_input = "derpaderp";
$password_salt = "aderp";
$arg=substr_replace($password_input, $password_salt, 4, 0);
$pass = hash('sha512', $arg);
if ( $digested_password_from_database == $pass ){ echo "success!"; }
Thanks for your replies folks.
精彩评论