【问题标题】:Password hash being generated differently every time每次生成不同的密码哈希
【发布时间】:2014-12-31 02:07:17
【问题描述】:

我正在使用密码保护我正在构建的码头服务器。我正在使用 Java 的 MessageDigest 类对密码进行哈希处理。我创建了这个测试类,它工作正常:

    String hash = "<hashOfMyPassword";
    String pass = "<myPassword>";
    byte[] data = pass.getBytes();
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    md.update(data);
    MessageDigest passMD = null;
    try {
        passMD = (MessageDigest) md.clone();
    } catch (CloneNotSupportedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    byte[] passHash = passMD.digest();
    System.out.println(passHash.toString().equals(hash));

但是当我将它移到我的码头服务器时,它开始表现得很奇怪。方法如下:

public void handle(String s, Request req, HttpServletRequest hreq,
            HttpServletResponse hres) throws IOException, ServletException {
        hres.setContentType("text/plain");
        hres.setStatus(HttpServletResponse.SC_OK);
        req.setHandled(true);
        if (!running) {

            //Validate password
            String pass = hreq.getParameter("password");
            hres.getWriter().println(pass);
            byte[] data = pass.getBytes();
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("SHA");
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            md.update(data);
            MessageDigest passMD = null;
            try {
                passMD = (MessageDigest) md.clone();
            } catch (CloneNotSupportedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            byte[] passHash = passMD.digest();
            hres.getWriter().println(passHash.toString());
            if (passHash.toString().equals(hash)) {
               //dostuff
            } else {
                hres.getWriter().println("invalid password");
            }
        } 
    }
}

(在任何人说话之前,我就知道我正在奇怪地传递密码,但这对于这个项目来说没关系)

这和以前完全一样,但这次我总是得到不同的哈希值,而且密码永远不会匹配。我两次传递相同的密码,第一次得到类似“[B@33ab7e65”,下一次得到“[B@58eb5b4”。

我正在使用 curl 顺便访问服务器。

对正在发生的事情有任何想法吗?这真的很奇怪。

【问题讨论】:

  • 全班第一。它是私有的静态字符串哈希。我事先生成了它。
  • 通过简单的散列来保护密码无效,我建议你改用PBKDF #2BcryptScrypt这样的算法。 Java 本身包含对PBKDF #2 的支持,其他的可以通过完善的公共库(例如 Bouncy Castle)获得。

标签: java hash jetty


【解决方案1】:

您正在将字节数组passHash 转换为带有toString 的字符串。这实际上根本没有获取数组的内容——Java 在数组上的toString 实现相当无用,它只是打印出数组在内存中的位置地址的一部分。

不要用字符串相等比较hash,直接比较!也可以将hash 输入为字节数组,然后使用Arrays.equals() 进行比较。

Arrays.equals(passHash, hash)

【讨论】:

    【解决方案2】:

    您的代码的问题是您在哈希上调用 toString() 而根本没有使用哈希。您不能通过调用 toString() 将字节数组转换为字符串。

     passHash.toString().equals(hash)
    

    【讨论】:

      【解决方案3】:

      Commons Lang 3 的 ArrayUtils 包含一种可靠的方法来生成数组的字符串版本。

         @Test
         public void arrayToString(){
            int[] a = {1,2,3};
            int[] b = Arrays.copyOf(a, 3);
            String aRawToString = a.toString();
            String bRawToString = b.toString();
            String aCommonsLangToString = ArrayUtils.toString(a);
            String bCommonsLangToString = ArrayUtils.toString(b);
            Assert.assertNotEquals(aRawToString, bRawToString);
            Assert.assertEquals(aCommonsLangToString, bCommonsLangToString);
            System.out.println(aRawToString);
            System.out.println(bRawToString);
            System.out.println(aCommonsLangToString);
            System.out.println(bCommonsLangToString);
         }
      

      下面的输出演示了使用 toString 的问题(它为相同的数组生成不同的答案)和解决方案。

      [I@504814f9
      [I@2c59109c
      {1,2,3}
      {1,2,3}
      

      这行代码来自原始问题:

      hres.getWriter().println(passHash.toString());
      

      可以改写为

      hres.getWriter().println(ArrayUtils.toString(passHash));
      

      生成一致的诊断输出。

      【讨论】:

        猜你喜欢
        • 2020-08-17
        • 2018-10-05
        • 1970-01-01
        • 2017-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-19
        • 2016-02-06
        相关资源
        最近更新 更多