2015-09-04 135 views
2

我需要验证使用python passlib生成的密码哈希。我的目标是使用passlib的pbkdf2_sha512方案来散列所有用户密码。但是,由于我们后端的特性,我需要从php脚本,js和java验证此密码。我没有发现任何一个库都可以使用passlib散列并验证密码。我想知道在我开始在php,js和java中实现passlib的哈希算法之前是否存在一个。验证由python passlib生成的密码哈希

回答

-2

在java中,您可以使用jython,它允许使用python库并执行python代码。

下面是示例Java函数使用passlib验证哈希:

Boolean verify_pbkdf2_sha512(String pw, String hash) { 

    PythonInterpreter python = new PythonInterpreter(); 

    python.exec("from passlib.hash import pbkdf2_sha512"); 

    python.set("pw", new PyString(pw)); 
    python.set("hash", new PyString(hash)); 

    python.exec("valid = 1 if pbkdf2_sha512.identify(hash) and pbkdf2_sha512.verify(pw, hash) else 0"); 

    Boolean valid = ((PyInteger)python.get("valid")).asInt()==1; 

    return (Boolean)valid; 
} 

你可以找到我的博客的更多信息:http://codeinpython.blogspot.com/2015/11/using-python-passlib-in-java.html

2

Passlib的pbkdf2_sha256哈希格式习俗passlib,所以有(可能? )不会有太多的端口可用于其他语言。但它是一个非常简单的PBKDF2-HMAC-SHA256算法+ base64编码封装,其中均为标准,并且应该具有其他语言的实现 - 所以它应该很容易移植。

但是,如果可移植性是优先级要求,则可能需要尝试使用passlib的bcryptsha256_crypt散列值。这两个都是标准的,并且应该有多种语言的实现。

请记住,bcrypt & sha256_crypt非常复杂 - 所以如果你无法根据你需要的语言找到一个端口,那么移植pbkdf2_sha256将比移植其中一个语言少很多。


另一个选择完全是通过子进程在python下调用passlib。 调用下面的Python oneliner ...

python3 -c 'import sys; from passlib.hash import pbkdf2_sha256 as ph; print(ph.verify(input(), input()))' 

......将让你写password\nhash\n到标准输入,并把它写回TrueFalse(或者如果哈希的格式不正确的错误消息)。

由于密码是通过标准输入写入的,因此这应该是相对安全的(与将它作为参数或env var传递相比)。

(该python2相当于是一样的,只是使用raw_input()代替input()

1

我可以为PHP这种解决方案:

/* 
* This function creates a passlib-compatible pbkdf2 hash result. Parameters are: 
* $algo  - one of the algorithms supported by the php `hash_pbkdf2()` function 
* $password - the password to hash, `hash_pbkdf2()` format 
* $salt  - a random string in ascii format 
* $iterations - the number of iterations to use 
*/ 
function create_passlib_pbkdf2($algo, $password, $salt, $iterations) 
{ 
    $hash = hash_pbkdf2($algo, $password, base64_decode(str_replace(".", "+", $salt)), $iterations, 64, true); 
    return sprintf("\$pbkdf2-%s\$%d\$%s\$%s", $algo, $iterations, $salt, str_replace("+", ".", rtrim(base64_encode($hash), '='))); 
} 

我复制的盐,迭代和算法出来的一个现有的passlib生成的哈希字符串,并为它们提供明文密码给该函数,它将生成与passlib相同的结果。

这里是一个PHP函数只是验证passlib PBKDF2密码,基于以上:

/* 
* This function verifies a python passlib-format pbkdf2 hash against a password, returning true if they match 
* only ascii format password are supported. 
*/ 
function verify_passlib_pbkdf2($password, $passlib_hash) 
{ 
    if (empty($password) || empty($passlib_hash)) return false; 

    $parts = explode('$', $passlib_hash); 
    if (!array_key_exists(4, $parts)) return false; 

    /* 
    * Results in: 
    * Array 
    * (
    *  [0] => 
    *  [1] => pbkdf2-sha512 
    *  [2] => 20000 
    *  [3] => AGzdiek7yUzJ9iorZD6dBPdy 
    *  [4] => 0298be2be9f2a84d2fcc56d8c88419f0819c3501e5434175cad3d8c44087866e7a42a3bd170a035108e18b1e296bb44f0a188f7862b3c005c5971b7b49df22ce 
    *) 
    */ 
    $t = explode('-', $parts[1]); 
    if (!array_key_exists(1, $t)) return false; 

    $algo = $t[1]; 
    $iterations = (int) $parts[2]; 
    $salt = $parts[3]; 
    $orghash = $parts[4]; 

    $hash = create_passlib_pbkdf2($algo, $password, $salt, $iterations); 
    return $passlib_hash === $hash; 
}