Using Django's auth user data from a client.
I currently have a project where I want to re-use the Django auth mechanism with a Java client application. This will prevent duplicating data and will allow individuals to add users via the Django admin while also utilizing the same authentication data with the Java client.
The idea is for the client software and Django to interoperate on the same table data that will also be updated or added too by the Java client application. The changes to the Django database need to be cross compatible when changes are made by either Django or the Java/client application.
While exploring this task I came to the realization that Django 4+ has changed the SHA encryption level. In short, do not use the code example in this post for anything other than Django 1.3.x.
Django stores a random salt and hash of a users password in the auth_user
table password column.
Here is an example from the password column of auth_user:
sha1$983483$25e5ec9766fc5c48661aeec78085012166c9be8d
We simply need to feed the random salt (the value after first $) and hashed password (value after second $) in the exact same order as Django expects to determine whether or not the supplied password and salt match the hash kept in the Django database. With my client being written in Java, so is the hash checking code.
The example below will return the hash in hex which can be used to match against the stored hash value in the Django database. Hashes are typically represented in hex because the raw value is binary.
Two arguments are passed. The first is password, the second is the random salt. After substituting these values into the example the output will match the hash kept in the Django auth_user table of your database.
The client operating on this data needs to select the user ID in the auth_table, retrieve the salt and hash, and pass these into the code below to determine whether or not the password is valid by comparing the original hash to the returned hash.
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHAHash {
public static String getHexHash(String password, String salt){
StringBuilder saltPass = new StringBuilder();
saltPass.append(salt);
saltPass.append(password);
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (md != null) {
md.update(saltPass.toString().getBytes());
}
byte byteData[] = new byte[0];
if (md != null) {
byteData = md.digest();
}
StringBuilder hexString = new StringBuilder();
for (byte aByteData : byteData) {
String hex = Integer.toHexString(0xff & aByteData);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
// Test
public static void main(String[] args) {
String hexHash = getHexHash("password", "983483");
System.out.println(hexHash)
}
}
Output:
25e5ec9766fc5c48661aeec78085012166c9be8d