Я пытаюсь создать контрольную сумму MD5 в ruby с помощью соли, но не могу найти способ сделать это с помощью стандартного пакета digest/md5.
Я знаю, что могу сделать это:
require 'digest/md5'
checksum = '$1$' + (Digest::MD5.new << plaintext).to_s
Однако, похоже, нет никакого способа указать соль для этой генерации контрольной суммы MD5 с помощью digest, и я не нашел никакого другого пакета, который я мог бы использовать для этого в ruby.
Это вообще возможно в ruby?
открытый текст => hippo, соль => q2w3e4, ожидаемый результат: $1$q2w3e4$WzKE5mnfb45yU6XNRLNJQ0

Вы можете добавить вычислить дайджест нескольких чанков вот так:
require 'digest/md5'
md5 = Digest::MD5.new
md5 << '$1$'
md5 << plaintext
checksum = md5.to_s
Или путем объединения строки соли и текста в одном вызове метода:
salt = '$1$'
checksum = Digest::MD5.hexdigest("#{salt}#{plaintext}")
Большое спасибо. Я пробовал это, но это не дало того же результата, что и хэширование для /etc/passwd. Я думаю, что соль не $1$ в этом случае. Однако я наткнулся на решение, и теперь я публикую его как свой ответ.
Я нашел следующее, и он делает то, что я хочу...
https://github.com/mogest/unix-crypt
Это работает следующим образом:
require 'unix_crypt'
checksum = UnixCrypt::MD5.build(plaintext, salt)
Это генерирует ту же контрольную сумму, что и в /etc/shadow, для чего я и хочу ее использовать,
UnixCrypt не просто добавляет соль к паролю. Внутри он делает более сложные вещи и даже несколько раз хеширует пароль.
Да, но он прост в использовании и работает так, как мне нужно для моей конкретной цели.
Если вы пытаетесь управлять системными паролями *nix, вам лучше просто использовать системные утилиты, а не создавать свои собственные. Однако, если вы хотите генерировать или проверять соленые пароли, используя только возможности ядра Ruby или стандартной библиотеки, вы, безусловно, можете это сделать.
Вычисленный пароль MD5 с солью обычно хранится в базе данных с плоскими файлами (например, /etc/shadow), где $ — разделитель полей:
$1$salt$hashed_pw
Обратите внимание, что первые два поля хранятся в открытом виде, потому что они необходимы для перестроения и хеширования правильной строки, когда представлен только пароль для проверки. В результате вам нужно рассматривать соль как переменную, отдельную от открытого текста пароля, хотя соль включается в пароль при хешировании.
Если у вас нет ограничения на количество символов, наложенного вашими утилитами, один из способов создать сильную соль — использовать SecureRandom#uuid для генерации значения UUIDv4. Например:
require 'securerandom'
salt = SecureRandom.uuid
#=> "c05280ef-151c-4ebc-83c6-f5f0906f89c2"
Затем вы можете вызвать свой хэш MD5 на salt + pw или pw + salt в зависимости от реализации пароля вашего приложения. Например:
require 'digest/md5'
MD5_STR_FMT = '$1$%s$%s'.freeze
salt = 'c05280ef-151c-4ebc-83c6-f5f0906f89c2'
pw = 'plaintext password gathered securely'
pw_digest = Digest::MD5.new << salt + pw
pw_entry = MD5_STR_FMT % [salt, pw_digest]
#=> "$1$c05280ef-151c-4ebc-83c6-f5f0906f89c2$87dcc23c0008e45526e474d0364e4aa5"
Затем вы сохраняете pw_entry в файле базы данных паролей, а затем анализируете соль, чтобы добавить ее перед предлагаемым паролем при повторном вычислении хэша во время аутентификации. Например:
require 'digest/md5'
# this is how we'll validate a password from user
# input against an entry from the password database
def valid_pw? pw, salt, hashed_pw
pw_digest = Digest::MD5.new << salt + pw
pw_digest.to_s.eql? hashed_pw.to_s
end
# extract salt and password from a database entry
def parse_pw_entry str
str.split(?$).slice -2, 2
end
# get this from your password database in whatever
# way you like
pw_entry = '$1$c05280ef-151c-4ebc-83c6-f5f0906f89c2$87dcc23c0008e45526e474d0364e4aa5'
# for demonstration purposes only; gather password
# securely from user, then perform your validation
['foo', 'plaintext password gathered securely'].map do |pw|
valid_pw? pw, *parse_pw_entry(pw_entry)
end
#=> [false, true]
Спасибо. Это очень полезная и полезная информация. Моя цель — проверить пароли в хранилище данных, отличном от /etc/shadow, которое используется для другого приложения, но в котором используется тот же механизм хеширования crypt-md5, что и в /etc/shadow.
Можете ли вы добавить пример ввода и ожидаемый результат?