Class CryptoUtil

java.lang.Object
org.apache.wiki.util.CryptoUtil

public final class CryptoUtil
extends java.lang.Object
Hashes and verifies salted SHA-1 passwords, which are compliant with RFC 2307.
  • Method Summary

    Modifier and Type Method Description
    protected static byte[] extractPasswordHash​(byte[] digest)
    Helper method that extracts the hashed password fragment from a supplied salted SHA digest by taking all of the characters before position 20.
    protected static byte[] extractSalt​(byte[] digest)
    Helper method that extracts the salt from supplied salted digest by taking all of the characters at position 20 and higher.
    static java.lang.String getSaltedPassword​(byte[] password)
    Creates an RFC 2307-compliant salted, hashed password with the SHA1 MessageDigest algorithm.
    protected static java.lang.String getSaltedPassword​(byte[] password, byte[] salt)
    Helper method that creates an RFC 2307-compliant salted, hashed password with the SHA1 MessageDigest algorithm.
    static void main​(java.lang.String[] args)
    Convenience method for hashing and verifying salted SHA-1 passwords from the command line.
    static boolean verifySaltedPassword​(byte[] password, java.lang.String entry)
    Compares a password to a given entry and returns true, if it matches.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • main

      public static void main​(java.lang.String[] args) throws java.lang.Exception

      Convenience method for hashing and verifying salted SHA-1 passwords from the command line. This method requires commons-codec-1.3.jar (or a newer version) to be on the classpath. Command line arguments are as follows:

      • --hash password - hashes password and prints a password digest that looks like this:
        {SSHA}yfT8SRT/WoOuNuA6KbJeF10OznZmb28=
      • --verify password digest - verifies password by extracting the salt from digest (which is identical to what is printed by --hash) and re-computing the digest again using the password and salt. If the password supplied is the same as the one used to create the original digest, true will be printed; otherwise false

      For example, one way to use this utility is to change to JSPWiki's build directory and type the following command:

      java -cp JSPWiki.jar:../lib/commons-codec-1.3.jar org.apache.wiki.util.CryptoUtil --hash mynewpassword
      Parameters:
      args - arguments for this method as described above
      Throws:
      java.lang.Exception - Catches nothing; throws everything up.
    • getSaltedPassword

      public static java.lang.String getSaltedPassword​(byte[] password) throws java.security.NoSuchAlgorithmException

      Creates an RFC 2307-compliant salted, hashed password with the SHA1 MessageDigest algorithm. After the password is digested, the first 20 bytes of the digest will be the actual password hash; the remaining bytes will be a randomly generated salt of length DEFAULT_SALT_SIZE, for example:

      {SSHA}3cGWem65NCEkF5Ew5AEk45ak8LHUWAwPVXAyyw==

      In layman's terms, the formula is digest( secret + salt ) + salt. The resulting digest is Base64-encoded.

      Note that successive invocations of this method with the same password will result in different hashes! (This, of course, is exactly the point.)

      Parameters:
      password - the password to be digested
      Returns:
      the Base64-encoded password hash, prepended by {SSHA}.
      Throws:
      java.security.NoSuchAlgorithmException - If your JVM is completely b0rked and does not have SHA.
    • getSaltedPassword

      protected static java.lang.String getSaltedPassword​(byte[] password, byte[] salt) throws java.security.NoSuchAlgorithmException

      Helper method that creates an RFC 2307-compliant salted, hashed password with the SHA1 MessageDigest algorithm. After the password is digested, the first 20 bytes of the digest will be the actual password hash; the remaining bytes will be the salt. Thus, supplying a password testing123 and a random salt foo produces the hash:

      {SSHA}yfT8SRT/WoOuNuA6KbJeF10OznZmb28=

      In layman's terms, the formula is digest( secret + salt ) + salt. The resulting digest is Base64-encoded.

      Parameters:
      password - the password to be digested
      salt - the random salt
      Returns:
      the Base64-encoded password hash, prepended by {SSHA}.
      Throws:
      java.security.NoSuchAlgorithmException - If your JVM is totally b0rked and does not have SHA1.
    • verifySaltedPassword

      public static boolean verifySaltedPassword​(byte[] password, java.lang.String entry) throws java.security.NoSuchAlgorithmException
      Compares a password to a given entry and returns true, if it matches.
      Parameters:
      password - The password in bytes.
      entry - The password entry, typically starting with {SSHA}.
      Returns:
      True, if the password matches.
      Throws:
      java.security.NoSuchAlgorithmException - If there is no SHA available.
    • extractPasswordHash

      protected static byte[] extractPasswordHash​(byte[] digest) throws java.lang.IllegalArgumentException
      Helper method that extracts the hashed password fragment from a supplied salted SHA digest by taking all of the characters before position 20.
      Parameters:
      digest - the salted digest, which is assumed to have been previously decoded from Base64.
      Returns:
      the password hash
      Throws:
      java.lang.IllegalArgumentException - if the length of the supplied digest is less than or equal to 20 bytes
    • extractSalt

      protected static byte[] extractSalt​(byte[] digest) throws java.lang.IllegalArgumentException
      Helper method that extracts the salt from supplied salted digest by taking all of the characters at position 20 and higher.
      Parameters:
      digest - the salted digest, which is assumed to have been previously decoded from Base64.
      Returns:
      the salt
      Throws:
      java.lang.IllegalArgumentException - if the length of the supplied digest is less than or equal to 20 bytes