问题描述
我有一个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 for crypt
,我看到它使用了一个特定于操作系统的 crypt
实现,所以我也在两个系统中测试了与Python相同结果的以下代码:
#include< unistd.h>
int main(){
char * des = crypt(test,$ 1 $ VFvON1xK $ ls4Zz4XTEuVI.1PnYm28.1);
puts(des);
}
如何将OS X的 crypt() / code>实现生成与Linux相同的结果
crypt()
?
为什么不是Python实现所涵盖(as我期望从这种情况下跨平台部署)?
这是因为Linux的glibc处理密码不同 - Linux上的密码盐对应于其生成的哈希类型。 OSX crypt()是普通的DES加密(这是可怕的)。
glibc支持各种哈希算法(MD5,Blowfish,SHA-256等) 。
如果我们来看看帮助页,我们可以看到:
如果盐是以字符$ id $开头的字符串,后跟
a以$结尾的字符串:
$ id $ salt $ encrypted
使用DES机器,id标识使用的加密方法
,然后确定其余的密码字符串如何解释
。支持以下id值:
ID |方法
--------------------------------------------- ------------
1 | MD5
2a | Blowfish(不在主线glibc;在一些
| Linux发行版中添加)
5 | SHA-256(自glibc 2.7起)
6 | SHA-512(因为glibc 2.7)
所以,给定信息..可以从你的密码第二个例子,使用Linux的crypt
$ 1 $ VFvON1xK $ SboCDZGBieKF1ns2GBfY50'('test',以salt = VFvON1xK加密)
1 == MD5
VFvON1xK == Salt
SboCDZGBieKF1ns2GBfY50 ==隐藏密码
幸运的是,有一个跨平台的解决方案,。
以下是如何使用它:
pre $
from passlib.hash import md5_crypt
hash = md5_crypt.encrypt(test,salt =VFvON1xK)
print hash
在Linux或OSX上运行时,会生成glibc友好的密码哈希值:
$ 1 $ VFvON1xK $ SboCDZGBieKF1ns2GBfY50
对于在Linux机器上产生的原始数据,这是一个隐性的。
I have a Django application which resets unix user passwords running in an Ubuntu machine, but my development environment is OS X and I've come across this annoying situation:
OS X:
>>> import crypt
>>> crypt.crypt('test','$1$VFvON1xK$')
'$1SoNol0Ye6Xk'
Linux:
>>> import crypt
>>> crypt.crypt('test','$1$VFvON1xK$')
'$1$VFvON1xK$SboCDZGBieKF1ns2GBfY50'
From reading the pydoc for crypt
, I saw it uses an OS-specific crypt
implementation, so I also tested the following code in both systems with the same results as Python:
#include <unistd.h>
int main() {
char *des = crypt("test","$1$VFvON1xK$ls4Zz4XTEuVI.1PnYm28.1");
puts(des);
}
How can I have OS X's crypt()
implementation generate the same results as Linux crypt()
?
And why isn't that covered by the Python implementation (as I would expect from such cases for cross-platform deployment)?
解决方案 This is because Linux's glibc handles passwords differently - the salt of the password on Linux corresponds to the type of hash that it generates. OSX crypt() is plain-old DES encryption, (which is horrible).
glibc supports a variety of hash algorithms (MD5, Blowfish, SHA-256, etc).
If we take a look at the crypt.3 manpage, we can see:
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)
So, given that information.. lets take your password from the second example using Linux's crypt
$1$VFvON1xK$SboCDZGBieKF1ns2GBfY50' ('test', encrypted with salt=VFvON1xK)
1 == MD5
VFvON1xK == Salt
SboCDZGBieKF1ns2GBfY50 == Hashed password
Luckily for you, there is a cross-platform solution for this, passlib.hash.md5_crypt.
Here's how you'd use it:
from passlib.hash import md5_crypt
hash = md5_crypt.encrypt("test",salt="VFvON1xK")
print hash
When run on Linux or OSX, produces the glibc friendly password hash of:
$1$VFvON1xK$SboCDZGBieKF1ns2GBfY50
Identical to the original produced on the Linux machine.
这篇关于在OSX中的python crypt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!