【问题标题】:python crypt in OSXOSX中的python crypt
【发布时间】:2012-10-14 15:50:48
【问题描述】:

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

操作系统:

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

Linux:

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

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

#include <unistd.h>

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

如何让 OS X 的 crypt() 实现产生与 Linux crypt() 相同的结果?
为什么 Python 实现没有涵盖这一点(正如我对跨平台部署的这种情况所期望的那样)?

【问题讨论】:

    标签: python c encryption


    【解决方案1】:

    这是因为 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 从第二个示例中获取您的密码

    $1$VFvON1xK$SboCDZGBieKF1ns2GBfY50' ('test', encrypted with salt=VFvON1xK)
    
    
    1                       == MD5
    VFvON1xK                == Salt
    SboCDZGBieKF1ns2GBfY50  == Hashed password
    

    幸运的是,有一个跨平台的解决方案,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 机器上制作的原版相同。

    【讨论】:

    • 我希望对核心 crypt 有一些额外的调整,但 passlib.hash.md5_crypt 也很好用!谢谢
    【解决方案2】:

    您将专门的盐字符串传递给调用特定于 glibc 的 crypt 行为的函数,这些行为在 Mac OS X 上不可用。来自 Debian 6 上的 crypt(3) 手册页:

    如果 salt 是一个以字符“$id$”开头的字符串,后跟一个以“$”结尾的字符串...那么 id 不使用 DES 机器,而是标识使用的加密方法,然后确定如何使用密码字符串的其余部分被解释。

    在您的 python 示例中,您告诉 crypt 使用 1 的 id,这会导致使用 M​​D5 而不是基于 DES 的散列。 Mac OS X 上没有这样的扩展,crypt 严格基于 DES。 (Mac OS X 的crypt 有它自己的扩展名——salt 可以是一个 9 字符数组,以下划线开头,后跟 4 个字节的迭代计数和 4 个字节的 salt——在 glibc 的实现中没有类似物。 )

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

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

    从安全角度来看,这显然很糟糕。考虑改用passlibpy-bcrypt 之类的东西。任何一个都可以同时为您带来更好的散列和跨平台可靠性。

    【讨论】:

      【解决方案3】:

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

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

      您可以编写一些东西,或找到一个模块,重新实现 crypt 在每个环境中使用的散列算法——但同样,这会破坏跨平台的目的。您将硬编码您的应用程序以在 Ubunutu 上运行,它可能使用不同的密码,不仅来自 OSX,而​​且来自其他 Unix 和 BSD 风格,如 RedHat、FreeBSD 等。

      【讨论】:

      • 我认为这个问题更尴尬,因为您不能将 mac 开发系统指向共享开发数据库并让它在使用相同数据库的 linux 前端上工作。
      • 确实,您提出了关于 crypt 的性能在该操作系统中应有的表现,谢谢。但我希望得到一个可以提到标准 python 库来解决我的问题的答案:)
      • 这个答案并没有真正回答这个问题:(例如,我在 OS X 上,我正在学习 python 并尝试使用 crypt()。我希望它产生与 Linux 版本相同的结果这样做是因为否则使用相同方法比较在不同平台上生成的哈希是没有意义的。如果加密哈希方法相同,则哈希不得跨平台更改。
      • 和原发帖人一样,你不了解答案,也不了解所涉及的技术。 Python 的crypt 不是加密哈希方法。这只是对操作系统自己的crypt 函数的调用。每个操作系统都以不同的方式实现crypt,因为它只是底层系统密码管理的标准接口。如果你想在不同平台上一致地散列字符串,你需要在每个平台上使用相同的加密散列方法——这意味着你不想使用crypt,而是想使用 hashlib 库或类似的东西。跨度>
      【解决方案4】:

      作为@synthesizerpatel 的answer 的更新,.encrypt() 方法现在在 passlib 中已弃用,并由.hash() 方法代替:

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

      【讨论】:

        猜你喜欢
        • 2013-05-05
        • 2014-09-24
        • 2019-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        相关资源
        最近更新 更多