OSX 中的 python 地穴

标签 python c encryption

我有一个 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 实现没有涵盖这一点(正如我对跨平台部署的这种情况所期望的那样)?

最佳答案

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

glibc 支持多种散列算法(MD5、Blowfish、SHA-256 等)。

如果我们看一下 crypt.3 manpage,我们可以看到:

   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 机器上生成的原始文件相同。

关于OSX 中的 python 地穴,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13052047/

相关文章:

Python - 从文件填充数组,避免最后断行

python - 在 Python 中转换时间

Python 线程错误组参数目前必须为 None

ruby - 敏感数据加密 - DataMapper + Sinatra

java - 在 Linux 上运行的 Java 应用程序中使用 PGP 兼容的文件加密的推荐解决方案?

python - 如何让生成器/迭代器在耗尽时评估为 False?

c - 在 C 中测试传递给函数的字符串中的第 n 个字符 == "x"的正确方法

c++ - C/C++实现并传递代码

c - 如何在 c make 文件中包含 clock_gettime

c++ - CryptImportKey Windows 8.1 使用 AES_256 PLAINTEXTKEYBLOB