OSX中的python crypt

2024-10-02 20:36:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Django应用程序,可以重置在Ubuntu机器上运行的unix用户密码,但我的开发环境是OS X,我遇到了这样一个令人讨厌的情况:

苹果操作系统:

>>> import crypt
>>> crypt.crypt('test','$1$VFvON1xK$')
'$1SoNol0Ye6Xk'

Linux系统:

^{pr2}$

通过阅读crypt的pydoc,我看到它使用了一个特定于操作系统的crypt实现,因此我还测试了两个系统中的以下代码,结果与Python相同:

#include <unistd.h>

int main() {
        char *des = crypt("test","$1$VFvON1xK$ls4Zz4XTEuVI.1PnYm28.1");
        puts(des);
}

如何让OSX的crypt()实现生成与Linux相同的结果?
为什么Python实现没有涵盖这一点(正如我在跨平台部署中所期望的那样)?在


Tags: django用户test机器应用程序密码环境ubuntu
3条回答

您将向函数传递特殊的salt字符串,该函数调用Mac OS X上不可用的glibc特定crypt行为

If salt is a character string starting with the characters "$id$" followed by a string terminated by "$"...then instead of using the DES machine, id identifies the encryption method used and this then determines how the rest of the password string is interpreted.

在python示例中,告诉crypt使用1的id,这将导致使用MD5而不是基于DES的散列。macosx上没有这样的扩展,其中crypt严格基于DES。(MacOSX的crypt有自己的扩展salt可以是一个9字符的数组,以下划线开头,后面是4个字节的迭代计数,4个字节的salt在glibc的实现中没有类似项。)

如果在两个平台上都避免了crypt扩展,而使用传统的crypt,其中salt只能是两个字节,那么在两个平台上从函数中得到的结果是相同的,例如:

>>> crypt.crypt( "test", "S/" )
'S/AOO.b04HTR6'

从安全角度来看,这显然很糟糕。考虑使用passlib或{a2}之类的东西。任何一种方法都可以让你同时获得更好的哈希和跨平台可靠性。在

这是因为Linux的glibc处理密码的方式不同——Linux上的密码盐对应于它生成的哈希类型。OSX crypt()是普通的旧DES加密(这很可怕)。在

glibc支持多种哈希算法(MD5、Blowfish、SHA-256等)。在

如果我们看一下crypt.3手册页,我们可以看到:

   If salt is a character string starting with the characters "$id$" followed by
   a string terminated by "$":

          $id$salt$encrypted

   then instead of using the DES machine, id identifies the encryption method
   used 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)

所以,考虑到这些信息。。让我们从第二个例子中使用Linux的crypt获取您的密码

^{pr2}$

幸运的是,有一个跨平台的解决方案,passlib.hash.md5_crypt。在

你怎么用的:

from passlib.hash import md5_crypt
hash = md5_crypt.encrypt("test",salt="VFvON1xK")
print hash

在Linux或OSX上运行时,生成glibc友好的密码哈希:

$1$VFvON1xK$SboCDZGBieKF1ns2GBfY50

与Linux机器上的原始版本相同。在

为什么要在Python中使用一个crypt函数?如果你在OSX上运行,你需要OSX版本的crypt(),如果你在ubuntu中运行,它将使用ubuntu的crypt()。在

这是一个跨平台的解决方案-Python使用OS crypt来确保环境中的兼容性。如果Python使用它自己的crypt(),那么哈希值将是相同的,但它可以在OSX上工作,而不能在Ubuntu上工作(反之亦然)

你可以写一些东西,或者找到一个模块,来重新实现crypt在每个环境中使用的哈希算法,但同样,这会破坏跨平台的目的。你需要对你的应用程序进行硬编码,以便在Ubunutu上工作,它可能使用不同的密码,不仅仅是来自OSX,还包括其他Unix和BSD风格,如RedHat、FreeBSD等

相关问题 更多 >