【问题标题】:Invalid salt revision when comparing Python generated hash with raw password in Java将 Python 生成的哈希与 Java 中的原始密码进行比较时,盐修订无效
【发布时间】:2018-08-12 04:55:54
【问题描述】:

所以我创建了一个数据库,用于存储用户信息和他们的哈希密码,该密码使用 Python 脚本使用bcrypt 模块进行哈希处理。

现在要使用我的 Java 客户端登录,我正在使用 JBCrypt 库作为我的 IntelliJ 项目中的 Maven 依赖项。它检索哈希并且数据库连接正常工作,唯一的问题是它抛出了这个错误:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Invalid salt revision
    at org.mindrot.jbcrypt.BCrypt.hashpw(BCrypt.java:671)
    at org.mindrot.jbcrypt.BCrypt.checkpw(BCrypt.java:763)
    at mypackage.Login.validateUser(Login.java:81)
    at mypackage.Login.actionPerformed(Login.java:63)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:269)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6578)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3343)
    at java.desktop/java.awt.Component.processEvent(Component.java:6343)
    at java.desktop/java.awt.Container.processEvent(Container.java:2259)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4961)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2317)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4793)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4539)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4480)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2303)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2758)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4793)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:766)
    at java.desktop/java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:717)
    at java.desktop/java.awt.EventQueue$3.run(EventQueue.java:711)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:89)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:99)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:739)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:737)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:89)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:736)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:199)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

检查代码如下:

String dbHash = results.getString("password");
System.out.println(dbHash);
boolean result = BCrypt.checkpw(new String(passwordField.getPassword()), dbHash);

编辑: Python 模块脚本中散列密码和原始密码的示例如下:

Raw:    zO/15;w|c'*uftH)
Hashed: $2b$12$7Y4ZmORuoH0dziYSg8dpd.PfvWQx2QPcoiRoGWg.HKfhuN6evEZnO

**编辑:** 我注意到这是因为 JBCrypt 似乎不支持大于 $2a 哈希的任何内容。我找不到 Python 的 bcrypt 模块文档,因此我无法确定是否可以在 Python 代码中使用 $2a 哈希。

【问题讨论】:

  • 请发布一个散列+实际密码的示例。
  • @lexicore 更新了 OP
  • 是的,好像是不兼容的版本。 $2a$... 会去的。
  • @lexicore 你是说JBCrypt 需要$2a$... 盐吗?也许 Python 模块中有一种方法可以使用它
  • 我是说$2b$ 显然不受支持。这些前缀似乎表示哈希的一个版本。从快速谷歌搜索看起来像$2a$was vulnerable。也许 jbcrypt 还没有更新?最后一次发布是 2015 年。

标签: java python bcrypt jbcrypt


【解决方案1】:

问题是JBCrypt 的问题。它已过时(它只能验证 $2a 哈希。

因此,为了解决这个问题,我不得不更改 Python 脚本以生成使用 $2a 前缀的盐:

可调整前缀

bcrypt 的另一个功能是可调节的 前缀让您定义您将保持兼容的库。 要对此进行调整,请将 2a 或 2b(默认值)传递给 bcrypt.gensalt(prefix=b"2b") 作为字节对象。

https://pypi.python.org/pypi/bcrypt/3.1.0

【讨论】:

    【解决方案2】:

    从源代码看来,异常来自checking the format of the hashed password

        if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
            throw new IllegalArgumentException ("Invalid salt version");
        if (salt.charAt(2) == '$')
            off = 3;
        else {
            minor = salt.charAt(2);
            if (minor != 'a' || salt.charAt(3) != '$')
                throw new IllegalArgumentException ("Invalid salt revision");
            off = 4;
        }
    

    所以我的猜测是 dbHash 出于某种原因与格式不匹配。要么它是由不兼容的版本生成的。或者它实际上没有散列。或为空。

    【讨论】:

    • 我已经打印了哈希并使用在线生成器检查了它。所以一定是不兼容的密码
    • @madcrazydrumma 您是否有机会实际发布密码+散列密码的示例?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2013-02-13
    • 2015-08-15
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多