Fil*_*ina 10 c python encryption
我有一个Django应用程序,它重置在Ubuntu机器上运行的unix用户密码,但我的开发环境是OS X,我遇到了这种烦人的情况:
OS X:
>>> import crypt
>>> crypt.crypt('test','$1$VFvON1xK$')
'$1SoNol0Ye6Xk'
Linux的:
>>> import crypt
>>> crypt.crypt('test','$1$VFvON1xK$')
'$1$VFvON1xK$SboCDZGBieKF1ns2GBfY50'
从阅读pydoc开始crypt,我看到它使用了特定于操作系统的crypt实现,因此我还在两个系统中测试了以下代码,结果与Python相同:
#include <unistd.h>
int main() {
        char *des = crypt("test","$1$VFvON1xK$ls4Zz4XTEuVI.1PnYm28.1");
        puts(des);
}
我如何让OS X的crypt()实现产生与Linux相同的结果crypt()?
为什么Python实现没有涵盖这一点(正如我对跨平台部署的这种情况所期望的那样)?  
syn*_*tel 12
这是因为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机器上生成的原始文件相同.
您将专门的salt字符串传递给函数,该函数调用Mac OS X上不可用的glibc特定的crypt行为.来自Debian 6上的crypt(3)手册页:
如果salt是一个字符串,以字符"$ id $"开头,后跟一个以"$"结尾的字符串...那么id不是使用DES机器,而是标识所使用的加密方法,然后确定其余的密码字符串被解释.
在你的python示例中,你告诉crypt使用id1,这会导致使用MD5而不是基于DES的散列.在Mac OS X上没有这样的扩展,crypt严格基于DES.(Mac OS X crypt有自己的扩展 -  salt可以是9个字符的数组,以下划线开头,后跟4个字节的迭代计数和4个字节的盐 - 在glibc的实现中没有模拟.)
如果你避免crypt在两个平台上使用扩展并使用传统的crypt,其中salt只能是两个字节,你将从两个平台上的函数得到相同的结果,例如:
>>> crypt.crypt( "test", "S/" )
'S/AOO.b04HTR6'
从安全角度来看,这显然是可怕的.考虑使用像passlib或py-bcrypt这样的东西.任何一个都可以同时为您提供更好的散列和跨平台可靠性.