I'm converting a Python project to Rails, both of them uses the same database and I'm trying to use Ruby to verify the passwords that are saved using Python library called passlib.hash.sha256_crypt. I want to use Ruby to verify the user input whether it is the valid password compared to the saved password using any Ruby library but couldn't find any suitable gem for that.
Example password saved in SHA256 using Python Passlib library:
$5$rounds=110000$4QB3mR7z8SVQwVDt$1jT2mdn9XHRD.O8gsCJXoUTDWJSLrY09uD8KZp78ou6
which is password
The gems that I've found are:
- Ruby Digest library
: not generating in the format of
$5$.....
- Unix Crypt : generate digests in relevant format but unable to verify the result
- Gibberish : only advance in AES mode decryption, not generating in the format of
$5$.....
Unix Crypt is the most relevant solution but the generated digest for the string "password" is different from the Python generated. I tried to remove the rounds
from the saved digest and verify it but it failed, I think it's because they are using different rounds
to generate the digest.
[7] pry(main)> UnixCrypt::SHA256.build("password")
=> "$5$qbpSpYyYoTCr0q4G$/jyjVRgg3Y4vQj39f9OWwUQhKOh70bTB50jH7WfsZl2"
[10] pry(main)> UnixCrypt.valid?("password", "$5$rounds=110000$4QB3mR7z8SVQwVDt$1jT2mdn9XHRD.O8gsCJXoUTDWJSLrY09uD8KZp78ou6")
=> false
[11] pry(main)> UnixCrypt.valid?("password", "$5$4QB3mR7z8SVQwVDt$1jT2mdn9XHRD.O8gsCJXoUTDWJSLrY09uD8KZp78ou6")
=> false
Based on @Niel Slater's comment, I used UnixCrypt's build
to rehash "password", and it's still different from the Python hashed string.
[81] pry(main)> UnixCrypt::SHA256.build("password", "4QB3mR7z8SVQwVDt", 110000)
=> "$5$rounds=110000$4QB3mR7z8SVQwVDt$hF/KhMEITeydgv58fXf2brManFYwhhy.dMqGnrkrLb1"
Any workaround on this, or is there any simpler method to verify the user password in Ruby? I'm not familiar with encryption, any detailed explanation on rounds and digests are welcomed too.
$
in the Python version), so you will never see the same hash. You can confirm this by re-hashing "password" in Python, and noticing it is different each time. The failure to validate is more of an issue, and means there is some other difference in the formats and/or algorithms between the python and Ruby versions. – Neil Slater