Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8808153
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T02:33:00+00:00 2026-06-14T02:33:00+00:00

I try to mimic the way Drupal 7 is checking for a correct password

  • 0

I try to mimic the way Drupal 7 is checking for a correct password in Java.
Found some code as a guideline here: https://github.com/CraftFire/AuthDB-Legacy/blob/master/src/main/java/com/authdb/scripts/cms/Drupal.java and extracted the code i needed.

The thing is however that when i give the password and the hashed version (in order to extract the salt and amount of iterations needed), i get different results.

The passwords are generated using the Drupal password-hash script
resulting in:

Expected   value = $S$DxVn7wubSRzoK9X2pkGx4njeDRkLEgdqPphc2ZXkkb8Viy8JEGf3
Calculated value = $S$DxVn7wubSpQ1CpUnBZZHNqIXMp2XMVZHMYBqAs24NsUHMY7HBkYn

Expected   value = $S$DOASeKfBzZoqgSRl/mBnK06GlLESyMHZ81jyUueEBiCrkkxxArpR
Calculated value = $S$DOASeKfBzs.XMVZ1NkYXNmIqMpEHAoEaMYJ1NmUHCZJaBZFnAZFX

Anyone able to help me / tell me what i’m doing wrong here?
Thanks.

Code:

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

class test {

  public static void main(String args[]) {
   // Passwords and hashes generated by Drupal.
   checkPassword("test"  , "$S$DxVn7wubSRzoK9X2pkGx4njeDRkLEgdqPphc2ZXkkb8Viy8JEGf3"); 
   checkPassword("barbaz", "$S$DOASeKfBzZoqgSRl/mBnK06GlLESyMHZ81jyUueEBiCrkkxxArpR");
  }

  private static String itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  private static final int DRUPAL_HASH_LENGTH = 55;
  private static int password_get_count_log2(String setting) { return itoa64.indexOf(setting.charAt(3)); }

  /**
   * Note: taken from the default Drupal 7 password algorithm
   * @param candidate
   *        the clear text password
   * @param saltedEncryptedPassword
   *        the salted encrypted password string to check => NEEDS TO BE THE DEFAULT DRUPAL 7 PASSWORD HASH.
   * @return true if the candidate matches, false otherwise.
   */
  public static boolean checkPassword(String candidate, String saltedEncryptedPassword) {
    if (candidate == null) {
      return false;
    }
    if (saltedEncryptedPassword == null) {
      return false; 
    }

    String hash = password_crypt(candidate, saltedEncryptedPassword);
    System.out.println("Tested value = " + saltedEncryptedPassword);
    System.out.println("Calced value = " + hash);

    return hash == saltedEncryptedPassword;
  }

  public static String SHA512(String text) {
    byte[] sha1hash = new byte[40];
    try {
      MessageDigest md = MessageDigest.getInstance("SHA-512");
      md.update(text.getBytes("UTF-8"), 0, text.length());
      sha1hash = md.digest();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return convertToHex(sha1hash);
  }

  private static String convertToHex(byte[] data) {
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
      int halfbyte = (data[i] >>> 4) & 0x0F;
      int two_halfs = 0;
        do {
          if ((0 <= halfbyte) && (halfbyte <= 9))
            buf.append((char) ('0' + halfbyte));
          else
            buf.append((char) ('a' + (halfbyte - 10)));
            halfbyte = data[i] & 0x0F;
      }
      while(two_halfs++ < 1);
    }
    return buf.toString();
  }

  private static String password_crypt(String password, String setting) {
    // The first 12 characters of an existing hash are its setting string.
    setting = setting.substring(0, 12);
    int count_log2 = password_get_count_log2(setting);

    String salt = setting.substring(4, 12);
    // Hashes must have an 8 character salt.
    if (salt.length() != 8) {
      return null; 
    }

    // Convert the base 2 logarithm into an integer.
    int count = 1 << count_log2;

    String hash;
    try {
      hash = SHA512(salt + password);
      do {
        hash = SHA512(hash + password);
      } while (--count >= 0);
    } catch(Exception e) {
      return null; 
    }

    int len = hash.length();
    String output = setting + password_base64_encode(hash, len);         
    return (output.length() > 0) ? output.substring(0, DRUPAL_HASH_LENGTH) : null;
  }

  private static String password_base64_encode(String input, int count) {
    StringBuffer output = new StringBuffer();
    int i = 0, value;
    do {
      value = input.charAt(i++);
      output.append(itoa64.charAt(value & 0x3f));
      if (i < count) {
        value |= input.charAt(i) << 8;
      }
      output.append(itoa64.charAt((value >> 6) & 0x3f));
      if (i++ >= count) {
        break;
      }
      if (i < count) {
        value |= input.charAt(i) << 16;
      }
      output.append(itoa64.charAt((value >> 12) & 0x3f));
      if (i++ >= count) {
        break;
      }
      output.append(itoa64.charAt((value >> 18) & 0x3f));
    } while (i < count);
    return output.toString();
  }

}

—
ps.
One thing i already see is the following:
Consider these functions:

  public String convertToHex(byte[] data) {
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) {
      int halfbyte = (data[i] >>> 4) & 0x0F;
      int two_halfs = 0;
        do {
          if ((0 <= halfbyte) && (halfbyte <= 9))
            buf.append((char) ('0' + halfbyte));
          else
            buf.append((char) ('a' + (halfbyte - 10)));
            halfbyte = data[i] & 0x0F;
      }
      while(two_halfs++ < 1);
    }
    return buf.toString();
  }

and

  public String convertToHex(byte [] raw) {
      StringBuilder hex = new StringBuilder(2 * raw.length);
      for (final byte b : raw) {
         int hiVal = (b & 0xF0) >> 4;
         int loVal = b & 0x0F;
         hex.append((char) ('0' + (hiVal + (hiVal / 10 * 7))));
         hex.append((char) ('0' + (loVal + (loVal / 10 * 7))));
      }
      return hex.toString();
   }

The first function returns the string as a lowercase, the second is returned as higher case string. Don’t know which to use, both are returning different results in the end, but neither is satisfying.

-Edit-

Almost there???…

Came a step further, changes the question a bit…
In Drupal the following function is used:

$hash = hash($algo, $salt . $password, TRUE);

that returns

'���Y�emb
ӈ3����4��q����h�osab��V�!IS�uC�*[�

As you see, we do not need the hex version, since you get a total different hash back…
So i altered the code in java:

  public byte[] SHA512(String text) {
    byte[] sha1hash = new byte[50];
    try {
      MessageDigest md = MessageDigest.getInstance("SHA-512");
      md.update(text.getBytes("UTF-8"), 0, text.length());
      sha1hash = md.digest();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return sha1hash;
  }

 --snip--
  hash = new String(SHA512(salt + password));
  System.out.println(hash);

that returns:

'���Y�emb
ӈ3����4��q���h�osab��V�!IS�uC�*[�

As you see thats ALMOST the same….

php:  ӈ3����4��q����h�osab��V�!IS�uC�*[�
java: ӈ3����4��q���h�osab��V�!IS�uC�*[�

Anyone got a clue how to fix that last part?
The form new String(SHA512(salt + password,’Whatevercodec’)); did not help me…
Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T02:33:02+00:00Added an answer on June 14, 2026 at 2:33 am

    I suggest that you do something like this:

    import java.security.NoSuchAlgorithmException;
    
    public class hash {
    
    private static final int DRUPAL_HASH_LENGTH = 55;
    
    private static String _password_itoa64() {
        return "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    }
    
    public static void main(String args[]) throws Exception {
        // Passwords and hashes generated by Drupal.
        checkPassword("adrian", "$S$DNbBTrkalsPChLsqajHUQS18pBBxzSTQW0310SzivTy7HDQ.zgyG");
        checkPassword("test"  , "$S$DxVn7wubSRzoK9X2pkGx4njeDRkLEgdqPphc2ZXkkb8Viy8JEGf3");
        checkPassword("barbaz", "$S$DOASeKfBzZoqgSRl/mBnK06GlLESyMHZ81jyUueEBiCrkkxxArpR");
    }
    
    
    private static int password_get_count_log2(String setting) {
        return _password_itoa64().indexOf(setting.charAt(3));
    }
    
    
    private static byte[] sha512(String input) {
        try {
            return java.security.MessageDigest.getInstance("SHA-512").digest(input.getBytes());
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return new byte[0];
    }
    
    private static byte[] sha512(byte[] input) {
        try {
            return java.security.MessageDigest.getInstance("SHA-512").digest(input);
        } catch (NoSuchAlgorithmException ex) {
            ex.printStackTrace();
        }
        return new byte[0];
    }
    
    /**
     * Note: taken from the default Drupal 7 password algorithm
     *
     * @param candidate               the clear text password
     * @param saltedEncryptedPassword the salted encrypted password string to check => NEEDS TO BE THE DEFAULT DRUPAL 7 PASSWORD HASH.
     * @return true if the candidate matches, false otherwise.
     */
    public static boolean checkPassword(String candidate, String saltedEncryptedPassword) throws Exception {
        if (candidate == null || saltedEncryptedPassword == null) {
            return false;
        }
    
        String hash = password_crypt(candidate, saltedEncryptedPassword);
        System.out.println("Expected value = " + saltedEncryptedPassword);
        System.out.println("Calced   value = " + hash);
        System.out.println("Result Good?   = " + saltedEncryptedPassword.equalsIgnoreCase(hash));
    
    
        return saltedEncryptedPassword.equalsIgnoreCase(hash);
    }
    
    
    private static String password_crypt(String password, String passwordHash) throws Exception {
        // The first 12 characters of an existing hash are its setting string.
        passwordHash = passwordHash.substring(0, 12);
        int count_log2 = password_get_count_log2(passwordHash);
        String salt = passwordHash.substring(4, 12);
        // Hashes must have an 8 character salt.
        if (salt.length() != 8) {
            return null;
        }
    
        int count = 1 << count_log2;
    
    
        byte[] hash;
        try {
            hash = sha512(salt.concat(password));
    
            do {
                hash = sha512(joinBytes(hash, password.getBytes("UTF-8")));
            } while (--count > 0);
        } catch (Exception e) {
            System.out.println("error " + e.toString());
            return null;
        }
    
        String output = passwordHash + _password_base64_encode(hash, hash.length);
        return (output.length() > 0) ? output.substring(0, DRUPAL_HASH_LENGTH) : null;
    }
    
    private static byte[] joinBytes(byte[] a, byte[] b) {
        byte[] combined = new byte[a.length + b.length];
    
        System.arraycopy(a, 0, combined, 0, a.length);
        System.arraycopy(b, 0, combined, a.length, b.length);
        return combined;
    }
    
    
    
    private static String _password_base64_encode(byte[] input, int count) throws Exception {
    
        StringBuffer output = new StringBuffer();
        int i = 0;
        CharSequence itoa64 = _password_itoa64();
        do {
            long value = SignedByteToUnsignedLong(input[i++]);
    
            output.append(itoa64.charAt((int) value & 0x3f));
            if (i < count) {
                value |= SignedByteToUnsignedLong(input[i]) << 8;
            }
            output.append(itoa64.charAt((int) (value >> 6) & 0x3f));
            if (i++ >= count) {
                break;
            }
            if (i < count) {
                value |=  SignedByteToUnsignedLong(input[i]) << 16;
            }
    
            output.append(itoa64.charAt((int) (value >> 12) & 0x3f));
            if (i++ >= count) {
                break;
            }
            output.append(itoa64.charAt((int) (value >> 18) & 0x3f));
        } while (i < count);
    
        return output.toString();
    }
    
    
    public static long SignedByteToUnsignedLong(byte b) {
        return b & 0xFF;
    }
    
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Try this code - import java.io.StringReader; public class StringReaderTest { public static void main(String[]
I'm new to EF 4.1 and try to move some code from to EF
Here's my code: HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(http://www.webcitation.org/comb.php); try
I have the following script below where I try to mimic a file upload
Try this piece of code - public class WhitespaceTest { public static void main(String[]
I am trying to mimic the functionality of this curl command in Java: curl
I try to mimic a network request send by a closed source application. The
I have the following (here simplified) code which I want to test with FakeItEasy
I try to mimic By writing my own custom view (to display individual stock
What is the definitive way to mimic the CSS property min-width in Internet Explorer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.