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:
So, given that information.. lets take your password from the second example using Linux’s crypt
Luckily for you, there is a cross-platform solution for this, passlib.hash.md5_crypt.
Here’s how you’d use it:
When run on Linux or OSX, produces the glibc friendly password hash of:
Identical to the original produced on the Linux machine.