我有一个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实现没有涵盖这一点(正如我在跨平台部署中所期望的那样)?在
您将向函数传递特殊的salt字符串,该函数调用Mac OS X上不可用的glibc特定crypt行为
在python示例中,告诉crypt使用1的
id
,这将导致使用MD5而不是基于DES的散列。macosx上没有这样的扩展,其中crypt
严格基于DES。(MacOSX的crypt
有自己的扩展salt可以是一个9字符的数组,以下划线开头,后面是4个字节的迭代计数,4个字节的salt在glibc的实现中没有类似项。)如果在两个平台上都避免了
crypt
扩展,而使用传统的crypt
,其中salt只能是两个字节,那么在两个平台上从函数中得到的结果是相同的,例如:从安全角度来看,这显然很糟糕。考虑使用passlib或{a2}之类的东西。任何一种方法都可以让你同时获得更好的哈希和跨平台可靠性。在
这是因为Linux的glibc处理密码的方式不同——Linux上的密码盐对应于它生成的哈希类型。OSX crypt()是普通的旧DES加密(这很可怕)。在
glibc支持多种哈希算法(MD5、Blowfish、SHA-256等)。在
如果我们看一下crypt.3手册页,我们可以看到:
所以,考虑到这些信息。。让我们从第二个例子中使用Linux的crypt获取您的密码
^{pr2}$幸运的是,有一个跨平台的解决方案,passlib.hash.md5_crypt。在
你怎么用的:
在Linux或OSX上运行时,生成glibc友好的密码哈希:
与Linux机器上的原始版本相同。在
为什么要在Python中使用一个crypt函数?如果你在OSX上运行,你需要OSX版本的crypt(),如果你在ubuntu中运行,它将使用ubuntu的crypt()。在
这是一个跨平台的解决方案-Python使用OS crypt来确保环境中的兼容性。如果Python使用它自己的crypt(),那么哈希值将是相同的,但它可以在OSX上工作,而不能在Ubuntu上工作(反之亦然)
你可以写一些东西,或者找到一个模块,来重新实现crypt在每个环境中使用的哈希算法,但同样,这会破坏跨平台的目的。你需要对你的应用程序进行硬编码,以便在Ubunutu上工作,它可能使用不同的密码,不仅仅是来自OSX,还包括其他Unix和BSD风格,如RedHat、FreeBSD等
相关问题 更多 >
编程相关推荐