Python script on OSX

I have a Django application that resets unix user passwords running on an Ubuntu machine, but my development environment is OS X and I came across this unpleasant situation:

OS X:

>>> import crypt >>> crypt.crypt('test','$1$VFvON1xK$') '$1SoNol0Ye6Xk' 

Linux:

 >>> import crypt >>> crypt.crypt('test','$1$VFvON1xK$') '$1$VFvON1xK$SboCDZGBieKF1ns2GBfY50' 

From reading pydoc for crypt I saw that it uses the crypt implementation for the OS, so I also tested the following code on 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 implement the implementation of the X crypt() OS for the same results as Linux crypt() ?
And why is this not covered by the Python implementation (as I would expect from such cases for cross-platform deployment)?

+8
c python encryption
source share
3 answers

This is because Linux glibc handles passwords differently - the Linux salt of the password matches the type of hash that it generates. OSX crypt () is simple DES encryption (which is awful).

glibc supports many hash algorithms (MD5, Blowfish, SHA-256, etc.).

If we 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, considering that the information .. allows you to take your password from the second example, using Linux crypt

 $1$VFvON1xK$SboCDZGBieKF1ns2GBfY50' ('test', encrypted with salt=VFvON1xK) 1 == MD5 VFvON1xK == Salt SboCDZGBieKF1ns2GBfY50 == Hashed password 

Fortunately for you there is a cross-platform solution for this, passlib.hash.md5_crypt .

Here's how you use it:

 from passlib.hash import md5_crypt hash = md5_crypt.encrypt("test",salt="VFvON1xK") print hash 

When run on Linux or OSX, a hash with friendly access is generated:

 $1$VFvON1xK$SboCDZGBieKF1ns2GBfY50 

Identical to the original created on a Linux machine.

+8
source share

You pass specialized salt strings to functions that cause glibc-type behavior that is not available on Mac OS X. From the crypt (3) man page on Debian 6:

If the salt is a character string starting with the characters "$ id $" followed by a line ending with "$" ... then instead of using the DES machine, the identifier identifies the encryption method used, and then determines how the rest of the password string is interpreted.

In your python examples, you say crypt uses an id of 1, which causes MD5 to be used instead of DES-based hashing. There is no such extension in Mac OS X, where crypt strictly DES. (Mac OS X crypt has its own extension - salt can be a 9-character array, starting with an underscore, followed by 4 bytes of iteration count and 4 bytes of salt, which has no analogue in the glibc implementation.)

If you avoid crypt extensions on both platforms and use the traditional crypt in which salt can only be two bytes, you will get the same results from the function on both platforms, for example:

 >>> crypt.crypt( "test", "S/" ) 'S/AOO.b04HTR6' 

This is obviously terrible in terms of security. Consider using something like passlib or py-bcrypt . Any of them will allow you to significantly improve hashing and cross-platform reliability at the same time.

+5
source share

why do you want to have one cryptographic function in Python? if you work on OSX, you need the osx crypt () version, and if you work on ubuntu, it will use ubuntu crypt ().

This is a cross-platform solution. Python uses OS cryptography to ensure compatibility in the environment. If Python used its own crypt (), the hashes would be the same - but it would work on OSX, not Ubuntu (or vice versa)

You could write something or find a module that reimplementes the hashing algorithm that uses crypto in each environment - but again, that could defeat the purpose of the cross platform. You will hardcode your application for working with Ubunutu, which can use various crypts not only from OSX, but also from other Unix and BSD, such as RedHat, FreeBSD, etc.

+1
source share

All Articles