使用Ruby验证Python生成的SHA256字符串

使用Ruby验证Python生成的SHA256字符串,python,ruby-on-rails,ruby,sha256,Python,Ruby On Rails,Ruby,Sha256,我正在将一个Python项目转换为Rails,它们都使用相同的数据库,我正在尝试使用Ruby来验证使用Python库保存的密码。我想使用Ruby来验证用户输入的密码是否有效,与使用任何Ruby库保存的密码相比,但找不到任何合适的gem 使用Python Passlib库保存在SHA256中的密码示例: $5$rounds=110000$4QB3mR7z8SVQwVDt$1jT2mdn9XHRD.O8gsCJXoUTDWJSLrY09uD8KZp78ou6 哪个是密码 我发现的宝石有: :不以$

我正在将一个Python项目转换为Rails,它们都使用相同的数据库,我正在尝试使用Ruby来验证使用Python库保存的密码。我想使用Ruby来验证用户输入的密码是否有效,与使用任何Ruby库保存的密码相比,但找不到任何合适的gem

使用Python Passlib库保存在SHA256中的密码示例:
$5$rounds=110000$4QB3mR7z8SVQwVDt$1jT2mdn9XHRD.O8gsCJXoUTDWJSLrY09uD8KZp78ou6
哪个是密码

我发现的宝石有:

  • :不以
    $5$…..的格式生成
  • :生成相关格式的摘要,但无法验证结果
  • :仅高级AES模式解密,不以
    $5$…
  • Unix Crypt是最相关的解决方案,但是为字符串“password”生成的摘要与Python生成的摘要不同。我试图从保存的摘要中删除
    轮数
    ,并对其进行验证,但失败了,我认为这是因为他们使用不同的
    轮数
    来生成摘要

    [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
    
    根据@nielslater的评论,我使用UnixCrypt的
    build
    来重新显示“密码”,它仍然不同于Python散列字符串

    [81] pry(main)> UnixCrypt::SHA256.build("password", "4QB3mR7z8SVQwVDt", 110000)
    => "$5$rounds=110000$4QB3mR7z8SVQwVDt$hF/KhMEITeydgv58fXf2brManFYwhhy.dMqGnrkrLb1"
    

    有没有解决方法,或者有没有更简单的方法在Ruby中验证用户密码?我不熟悉加密,也欢迎对回合和摘要进行详细解释。

    你的问题是你认为
    $5$rounds=110000$4QB3mR7z8SVQwVDt$1jT2mdn9XHRD.O8gsCJXoUTDWJSLrY09uD8KZp78ou6
    出于某种原因是密码的散列。事实并非如此

    在Python中:

    hash = sha256_crypt.encrypt("password", rounds=110000, salt='4QB3mR7z8SVQwVDt')
    # '$5$rounds=110000$4QB3mR7z8SVQwVDt$hF/KhMEITeydgv58fXf2brManFYwhhy.dMqGnrkrLb1'
    
    在Ruby中:

    UnixCrypt::SHA256.build("password",'4QB3mR7z8SVQwVDt', 110000 )
    # "$5$rounds=110000$4QB3mR7z8SVQwVDt$hF/KhMEITeydgv58fXf2brManFYwhhy.dMqGnrkrLb1"
    
    此外:


    因此,Ruby gem
    unix crypt
    是解决您的问题的最简单的选择,因为它与Python库
    passlib
    匹配的工作量最小(无需了解细节,只需始终使用相同的参数和字符串值).

    您的问题是,出于某种原因,您认为
    $5$rounds=110000$4QB3mR7z8SVQwVDt$1jT2mdn9XHRD.O8gsCJXoUTDWJSLrY09uD8KZp78ou6
    是密码的散列。事实并非如此

    在Python中:

    hash = sha256_crypt.encrypt("password", rounds=110000, salt='4QB3mR7z8SVQwVDt')
    # '$5$rounds=110000$4QB3mR7z8SVQwVDt$hF/KhMEITeydgv58fXf2brManFYwhhy.dMqGnrkrLb1'
    
    在Ruby中:

    UnixCrypt::SHA256.build("password",'4QB3mR7z8SVQwVDt', 110000 )
    # "$5$rounds=110000$4QB3mR7z8SVQwVDt$hF/KhMEITeydgv58fXf2brManFYwhhy.dMqGnrkrLb1"
    
    此外:


    因此,Ruby gem
    unix crypt
    是解决您的问题的最简单的选择,因为它与Python库
    passlib
    匹配的工作量最小(无需了解细节,只需在整个过程中使用相同的参数和字符串值)。

    字符串不同,因为它们包含一个随机变量(Python版本中第3个和第4个
    $
    之间的值),因此您将永远不会看到相同的散列。您可以通过重新散列“password”来确认这一点在Python中,每次都会注意到它是不同的。验证失败是一个更大的问题,这意味着Python和Ruby版本之间的格式和/或算法存在一些其他差异。字符串不同,因为它们包含一个随机salt(Python版本中第三个和第四个
    $
    之间的值),因此您将永远不会看到相同的哈希值。您可以通过在Python中重新哈希“password”来确认这一点,并注意到它每次都不同。验证失败是一个更大的问题,这意味着Python和Ruby版本在格式和/或算法上存在一些其他差异。这是我的错误,最终导致原始文本不一致“密码"好的。谢谢你的提示!UnixCrypt是一个很好的工具,但是自述文件不够详细,所以在我在rdoc中发现之前,我不知道
    round
    salt
    选项是否可用。这是一个简单的错误,一旦成为测试的一个假设,可能会让你挠头和浪费时间。我删除了我对可能出现的bug的评论,看起来Ruby和Python在算法的细节上非常一致。这是我的错误,结果原来的文本不是“密码”好的。谢谢你的提示!UnixCrypt是一个很好的工具,但是自述文件不够详细,所以在我在rdoc中发现之前,我不知道
    round
    salt
    选项是否可用。这是一个简单的错误,一旦成为测试的一个假设,可能会让你挠头和浪费时间。我删除了关于可能的bug的评论,看起来Ruby和Python在算法的细节上非常一致。