【问题标题】:Verifying password hashes generated by python passlib验证 python passlib 生成的密码哈希
【发布时间】:2015-11-30 05:04:04
【问题描述】:

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

【问题讨论】:

    标签: php python web-applications hash passwords


    【解决方案1】:

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

    这是使用 passlib 验证哈希的示例 java 函数:

    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()

      【讨论】:

        【解决方案3】:

        我可以为 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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-28
          • 1970-01-01
          • 2014-05-26
          • 1970-01-01
          • 2014-05-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多