edu.vt.middleware.password.AbstractDigester Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vt-password Show documentation
Show all versions of vt-password Show documentation
Library for checking that a password complies with a custom set of rules
The newest version!
/*
$Id: AbstractDigester.java 2704 2013-04-24 21:30:32Z dfisher $
Copyright (C) 2003-2013 Virginia Tech.
All rights reserved.
SEE LICENSE FOR MORE INFORMATION
Author: Middleware Services
Email: [email protected]
Version: $Revision: 2704 $
Updated: $Date: 2013-04-24 17:30:32 -0400 (Wed, 24 Apr 2013) $
*/
package edu.vt.middleware.password;
import edu.vt.middleware.crypt.digest.DigestAlgorithm;
import edu.vt.middleware.crypt.util.Converter;
/**
* Provides common implementation for password rules that use a digest.
*
* @author Middleware Services
* @version $Revision: 2704 $ $Date: 2013-04-24 17:30:32 -0400 (Wed, 24 Apr 2013) $
*/
public abstract class AbstractDigester
{
/** Digest object to use if comparing hashed passwords. */
protected DigestAlgorithm digest;
/** Converter to use in conjunction with the digest. */
protected Converter converter;
/**
* This will set the supplied digest algorithm to be used when password
* comparison are made. Useful if you need to compare password which are in a
* hashed form. See {@link edu.vt.middleware.crypt.digest.DigestAlgorithm}.
*
* @param algorithm to use for hashing
* @param conv to convert bytes to string
*/
public void setDigest(final String algorithm, final Converter conv)
{
digest = DigestAlgorithm.newInstance(algorithm);
converter = conv;
}
/**
* Determines whether an undigested password matches a (possibly digested)
* reference value.
*
* @param undigested candidate clear text password.
* @param reference reference password (possibly digested).
*
* @return true if passwords match, false otherwise.
*/
protected boolean matches(final String undigested, final String reference)
{
final String compare;
if (digest != null) {
final byte[] hash = converter.toBytes(reference);
final int saltLength = hash.length - digest.getDigest().getDigestSize();
// check if hash is longer than expected digest size
if (saltLength > 0) {
// extract the salt from the reference password
final byte[] salt = extractSalt(hash, saltLength);
// concatenate the salt to both the digest and the resulting output
final byte[] saltedHash = addSalt(
digest.digest(addSalt(undigested.getBytes(), salt)),
salt);
compare = converter.fromBytes(saltedHash);
} else {
compare = digest.digest(undigested.getBytes(), converter);
}
} else {
compare = undigested;
}
return reference.equals(compare);
}
/**
* Extracts a salt from the end of the supplied hash.
*
* @param hash to read salt from
* @param length of the salt to extract
*
* @return salt bytes
*/
protected byte[] extractSalt(final byte[] hash, final int length)
{
final byte[] salt = new byte[length];
System.arraycopy(hash, hash.length - length, salt, 0, length);
return salt;
}
/**
* Concatenates the supplied salt to the supplied data.
*
* @param data to concatenate salt to
* @param salt to concatenate
*
* @return new byte array of concatenated data
*/
protected byte[] addSalt(final byte[] data, final byte[] salt)
{
final byte[] saltedData = new byte[data.length + salt.length];
System.arraycopy(data, 0, saltedData, 0, data.length);
System.arraycopy(salt, 0, saltedData, data.length, salt.length);
return saltedData;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy