Переопределение членства в ASP.NET и хеширования паролей пользователей в Ruby - PullRequest
8 голосов
/ 10 февраля 2009

У меня есть большая база данных пользователей (~ 200 000), которую я перевожу из приложения ASP.NET в приложение Ruby on Rails. Я не хочу просить каждого пользователя сбросить свой пароль, и поэтому я пытаюсь повторно реализовать функцию хеширования пароля C # в Ruby.

Старая функция такова:

public string EncodePassword(string pass, string saltBase64)
 {
     byte[] bytes = Encoding.Unicode.GetBytes(pass);
     byte[] src = Convert.FromBase64String(saltBase64);
     byte[] dst = new byte[src.Length + bytes.Length];
     Buffer.BlockCopy(src, 0, dst, 0, src.Length);
     Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
     HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
     byte[] inArray = algorithm.ComputeHash(dst);
     return Convert.ToBase64String(inArray);
 }

Примером хэшированного пароля и соли является (и пароль использовался как «пароль»):

Хешированный пароль: "weEWx4rhyPtd3kec7usysxf7kpk =" Соль: "1ptFxHq7ALe7yXIQDdzQ9Q ==" Пароль: «пароль»

Теперь со следующим кодом Ruby:

require "base64"
require "digest/sha1"


password = "password"
salt = "1ptFxHq7ALe7yXIQDdzQ9Q=="

concat = salt+password

sha1 = Digest::SHA1.digest(concat)

encoded = Base64.encode64(sha1)

puts encoded

Я не получаю правильный хэш пароля (вместо "weEWx4rhyPtd3kec7usysxf7kpk =") я получаю "+ BsdIOBN / Vh2U7qWG4e + O13h3iQ =". Кто-нибудь может увидеть, в чем может быть проблема?

Большое спасибо

Arfon

Ответы [ 4 ]

8 голосов
/ 11 февраля 2009

Просто быстрое обновление, мой коллега решил это:

require "base64"
require "digest"
require "jcode"


def encode_password(password, salt)
 bytes = ""
 password.each_char { |c| bytes += c + "\x00" }
 salty = Base64.decode64(salt)
 concat = salty+bytes
 sha1 = Digest::SHA1.digest(concat)
 encoded = Base64.encode64(sha1).strip()
 puts encoded
end
3 голосов
/ 18 ноября 2011

Мне было поручено перенести существующее приложение .NET в Ruby on Rails. Я использую приведенный ниже код для имитации хеширования пароля .NET. Я очень новичок в Ruby и совсем не знаю .NET. Код может быть не таким чистым, как мог бы, но это начало.

Чтобы проверить, сохраните его как скрипт Ruby и запустите:

скрипт ruby ​​plain_text_password salt_in_base64

, например

ruby ​​dotNetHash.rb password123 LU7hUk4MXAvlq6DksvP9SQ ==

require "base64"
require "digest"

# Encode password as double-width characters
password_as_text = ARGV.first
double_width_password = []
double_width_password = password_as_text.encode("UTF-16LE").bytes.to_a

# Unencode the salt
salt = Base64.decode64(ARGV[1])

# Concatenate salt+pass
salt_pass_array = []
salt_pass_array = salt.bytes.to_a + double_width_password

# Repack array as string and hash it. Then encode.
salt_pass_str = salt_pass_array.pack('C*')
sha1_saltpass = Digest::SHA1.digest(salt_pass_str)
enc_sha1_saltpass = Base64.encode64(sha1_saltpass).strip()
puts "Encoded SHA1 saltpass is " + enc_sha1_saltpass
2 голосов
/ 10 февраля 2009

Вы довольно близко. К сожалению, в Ruby на данный момент нет встроенной поддержки юникода, и ваша хеш-функция основана на этом. Есть обходные пути. Посмотрите на сайте о том, как сделать Unicode в Ruby. Кстати, я думаю, что вы забыли base64 декодировать соль, похоже, что функция ASP.net делает это.

1 голос
/ 10 февраля 2009

Вам нужно расшифровать соль, чтобы преобразовать ее обратно в байтовое представление, а затем объединить ее с паролем, чтобы получить значение хешированного пароля. Вы используете кодирующую строку соли напрямую (которая является другой солью), и поэтому она хэширует что-то другое.

require "base64"
require "digest/sha1"
password = "password"
salt = Base64.decode64("1ptFxHq7ALe7yXIQDdzQ9Q==")
concat = salt+password
sha1 = Digest::SHA1.digest(concat)
encoded = Base64.encode64(sha1)
puts encoded
...