首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >crypt.crypt引发OSError:无效参数

crypt.crypt引发OSError:无效参数
EN

Stack Overflow用户
提问于 2021-04-22 23:47:55
回答 1查看 58关注 0票数 0

我使用的是最新的Debian10。我对python crypt.crypt有意外的行为,一些调用引发了OSError: Invalid Argument异常,没有进一步的解释,所以我不太确定发生了什么。

代码语言:javascript
复制
>>> # debian - python3.9
>>> import crypt
>>> crypt.crypt("foo", '$2a$10$Ud3Zhyb1M3I1PMDXWOFBp.81LKFwD5mZo33jnVHbPPrQY4cKSqoI7')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/crypt.py", line 82, in crypt
    return _crypt.crypt(word, salt)
OSError: [Errno 22] Invalid argument

>>> # archlinux - python3.9
>>> import crypt
>>> crypt.crypt("foo", '$2a$10$Ud3Zhyb1M3I1PMDXWOFBp.81LKFwD5mZo33jnVHbPPrQY4cKSqoI7')
'$2a$10$Ud3Zhyb1M3I1PMDXWOFBp.8U7GsUrAN2JZZbKcxHSc.cTrK6oEA/.'

这段代码在我的debian上用系统python3.7 (it returns None until python3.9)无声地失败了,并在我手动构建的python3.9上引发了这个OSError。在我的archlinux上,它在任何python版本上都能很好地工作。

edit1:我怀疑这是因为加密方法可能不再被debian支持了?

代码语言:javascript
复制
# On arch
>>> crypt.methods
[<crypt.METHOD_SHA512>, <crypt.METHOD_SHA256>, <crypt.METHOD_BLOWFISH>, <crypt.METHOD_MD5>, <crypt.METHOD_CRYPT>]

# On Debian
>>> crypt.methods
[<crypt.METHOD_SHA512>, <crypt.METHOD_SHA256>, <crypt.METHOD_MD5>, <crypt.METHOD_CRYPT>]

edit2: crypt手册页显示了这段有趣的信息:

代码语言:javascript
复制
If  salt  is  a character string starting with the characters "$id$" followed by a string
optionally terminated by "$", then the result has the form:

       $id$salt$encrypted

id identifies the encryption method used instead of DES and this then determines how
the rest of the password  string  is  interpreted.

The following values of id are supported:
ID  | Method
─────────────────────────────────────────────────────────
1   | MD5
2a  | Blowfish (not in mainline glibc; added in some
    | Linux distributions)
5   | SHA-256 (since glibc 2.7)
6   | SHA-512 (since glibc 2.7)

因此,盐开头的$2a意味着加密需要河豚才能正常工作,但根据crypt.method的说法,它在debian上不可用。

edit3:我可以用这段C代码来确认这一点

代码语言:javascript
复制
// gcc crypt.c -o foobar -lcrypt; ./foobar
#include <crypt.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>


int main() {
    char *crypt_result;
    char* word = "foo";
    char* salt = "$2a$10$Ud3Zhyb1M3I1PMDXWOFBp.81LKFwD5mZo33jnVHbPPrQY4cKSqoI7";

    crypt_result = crypt(word, salt);
    if (crypt_result == NULL) {
        printf("%s\n", strerror(errno));
    }
    else {
        printf("%s\n", crypt_result);
    }

    return 0;
}

它在archlinux上显示预期的输出,但在debian上显示Invalid argument

我该如何解决这种情况?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-23 01:04:53

更多上下文

盐开头的$2a是blowfish/bcrypt方法的标记。

并非所有的Linux发行版都支持Blowfish,比如Ubuntu:

How to make Ubuntu's crypt(3) support Blowfish?

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1349252

从Debian 10开始,Debian不支持crypt中的blowfish,但在下一个版本中应该能够做到这一点,将crypt的依赖从glibc移动到libxcrypt:

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=149452#42

https://blog.bofh.it/debian/id_458

如何解决这种情况

尝试使用passlib

我尝试将passlib与其原型类似于crypt.cryptverify上下文一起使用

代码语言:javascript
复制
>>> from passlib.apps import custom_app_context as pwd_context
>>> pwd_context.verify("foo", '$2a$10$Ud3Zhyb1M3I1PMDXWOFBp.81LKFwD5mZo33jnVHbPPrQY4cKSqoI7')

但不幸的是,这段代码是seems to be bugged

尝试使用bcrypt

现在,我将坚持使用crypt.crypt,并使用bcrypt作为后备:

代码语言:javascript
复制
import crypt
import bcrypt

def verify(password, hash):
    try:
        return crypt.crypt(password, hash) == hash
    except OSError:
        return bcrypt.checkpw(password.encode("utf-8"), hash.encode("utf-8"))

verify("foo", "$2a$10$Ud3Zhyb1M3I1PMDXWOFBp.81LKFwD5mZo33jnVHbPPrQY4cKSqoI7")
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67216636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档