【问题标题】:java hash from "PBKDF2WithHmacSHA512" is differs from python CRYPT(digest_alg='pbkdf2(1000,20,sha512)', salt=True)(password)[0])来自“PBKDF2WithHmacSHA512”的java哈希不同于python CRYPT(digest_alg='pbkdf2(1000,20,sha512)', salt=True)(password)[0])
【发布时间】:2017-04-21 11:45:06
【问题描述】:

我有一个使用以下 python 代码散列密码的数据库:

result = str(CRYPT(digest_alg='pbkdf2(1000,20,sha512)', salt=True)(password)[0])

(详情可查看here

对于密码='123',它会生成

pbkdf2(1000,20,sha512)$b3c56f341284f4be$54297564f7a3be8c6e9c10b27821f8105e0a8120

我需要使用 java 验证密码。我使用以下代码:

    validatePassword("123", "pbkdf2(1000,20,sha512)$b3c56f341284f4be$54297564f7a3be8c6e9c10b27821f8105e0a8120");



    private static boolean validatePassword(String originalPassword, String storedPassword) throws NoSuchAlgorithmException, InvalidKeySpecException
    {
        String[] parts = storedPassword.split("\\$");
        byte[] salt = fromHex(parts[1]);
        byte[] hash = fromHex(parts[2]);

        PBEKeySpec spec = new PBEKeySpec(originalPassword.toCharArray(), salt, 1000, hash.length * 8);
        SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
        byte[] testHash = skf.generateSecret(spec).getEncoded();

        System.out.println(toHex(testHash));
        System.out.println(toHex(hash));

        return true;
    }


    private static byte[] fromHex(String hex) throws NoSuchAlgorithmException
    {
        byte[] bytes = new byte[hex.length() / 2];
        for(int i = 0; i<bytes.length ;i++)
        {
            bytes[i] = (byte)Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }
        return bytes;
    }

    private static String toHex(byte[] array)
    {
        StringBuilder sb = new StringBuilder();
        for(int i=0; i< array.length ;i++)
        {
            sb.append(Integer.toString((array[i] & 0xff) + 0x100, 16).substring(1));
        }
        return sb.toString();
    }

但结果如下:

80385948513c8d1826a3a5b8abc303870d41d794
54297564f7a3be8c6e9c10b27821f8105e0a8120

请帮助我做错了什么?

【问题讨论】:

  • 我看不出有人在不知道CRYPT 是什么的情况下回答这个问题。
  • 类 gluon.validators.CRYPT(key=None, digest_alg='pbkdf2(1000, 20, sha512)', min_length=0, error_message='太短', salt=True, max_length=1024 )

标签: java python sha512 pbkdf2


【解决方案1】:

web2py 周围的代码中存在某种“错误”。

哈希看起来像一个十六进制字符串,但它只是作为十六进制字符串的字符表示发送到 hashlib.pbkdf2_hmac(openssl 方法的代理)。这意味着你不应该使用

byte[] salt = fromHex(parts[1]);

但是

byte[] salt = parts[1].getBytes("utf-8");

此外,您需要将 KEYLENGTH 而不是盐长度传递给 PBEKeySpec 的构造函数。

更正的部分应为:

byte[] salt = parts[1].getBytes("utf-8");
byte[] hash = fromHex(parts[2]);
PBEKeySpec spec = new PBEKeySpec(originalPassword.toCharArray(), salt, 1000, 20*8);

替换它并且代码有效。花了一段时间才发现这一点;)

【讨论】:

  • 非常感谢!!!真的行!我为这个错误道歉,因为我是 Java 新手。
  • 不需要借口,@krtl - 你没有错误,看起来来自 Web2py 的 Python 代码有错误;)
  • 是的,我已经明白了,只是稍后。不管怎样,你很棒!再次感谢您!
猜你喜欢
  • 2018-12-03
  • 2014-11-29
  • 1970-01-01
  • 2011-05-24
  • 2020-07-04
  • 2020-02-08
  • 1970-01-01
  • 2016-01-13
  • 2015-01-04
相关资源
最近更新 更多