在Python中复制Java密码哈希代码(PBKDF2WithHmacSHA1)
我一直在尝试将java密码身份验证复制到python中,但是得到的哈希是不同的 密码:abcd1234 密码令牌(java):$31$16$sWy1dDEx52vwQUCswXDYMQMzTJC39g1\u nmrK384T4-w 生成的密码令牌(python):$pbkdf2$16$c1d5MWRERXg1MnZ3UVVDcw$QPQVE4QBRNYJTMRXK0M7WLFH5U 根据Java代码,迭代是16,SALT应该是sWy1dDEx52vwQUCswXDYMQMzTJC39g1_nmrK384T4-w中的前16个字符,即sWy1dDEx52vwQUCs,散列应该是wXDYMQMzTJC39g1_nmrK384T4-w 但是,将变量应用到python中会得到不同的哈希结果,qpve4qbrnyjtmrxk0m7wlfh5u,这与Java的哈希不同 我错过了什么 爪哇:在Python中复制Java密码哈希代码(PBKDF2WithHmacSHA1),java,python,encryption,hash,password-encryption,Java,Python,Encryption,Hash,Password Encryption,我一直在尝试将java密码身份验证复制到python中,但是得到的哈希是不同的 密码:abcd1234 密码令牌(java):$31$16$sWy1dDEx52vwQUCswXDYMQMzTJC39g1\u nmrK384T4-w 生成的密码令牌(python):$pbkdf2$16$c1d5MWRERXg1MnZ3UVVDcw$QPQVE4QBRNYJTMRXK0M7WLFH5U 根据Java代码,迭代是16,SALT应该是sWy1dDEx52vwQUCswXDYMQMzTJC39g1_nmr
Java代码的原始链接:在Java代码的工作方式和passlib的pbkdf2_sha1 hasher的工作方式之间有很多不同之处
- java哈希字符串包含一个log cost参数,该参数需要传递
1
private static final String ALGORITHM = "PBKDF2WithHmacSHA1"; private static final int SIZE = 128; private static final Pattern layout = Pattern.compile("\\$31\\$(\\d\\d?)\\$(.{43})"); public boolean authenticate(char[] password, String token) { Matcher m = layout.matcher(token); if (!m.matches()) throw new IllegalArgumentException("Invalid token format"); int iterations = iterations(Integer.parseInt(m.group(1))); byte[] hash = Base64.getUrlDecoder().decode(m.group(2)); byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8); byte[] check = pbkdf2(password, salt, iterations); int zero = 0; for (int idx = 0; idx < check.length; ++idx) zero |= hash[salt.length + idx] ^ check[idx]; return zero == 0; }
from passlib.hash import pbkdf2_sha1 def hasher(password): size = 128 key0 = "abcd1234" iter = int(password.split("$")[2]) salt0 = password.split("$")[3][0: 16] hash = pbkdf2_sha1.using(rounds=iter, salt = salt0.encode()).hash(key0) print(hash.split('$')[4]) return hash
from passlib.utils.binary import b64s_decode, ab64_encode def adapt_java_hash(jhash): _, ident, cost, data = jhash.split("$") assert ident == "31" data = b64s_decode(data.replace("_", ".").replace("-", "+")) return "$pbkdf2$%d$%s$%s" % (1<<int(cost), ab64_encode(data[:16]), ab64_encode(data[16:])) >>> adapt_java_hash("$31$16$sWy1dDEx52vwQUCswXDYMQMzTJC39g1_nmrK384T4-w") '$pbkdf2$65536$sWy1dDEx52vwQUCswXDYMQ$AzNMkLf2DX.easrfzhPj7A'