package marubinotto.util;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.UnhandledException;
public class PasswordDigest {
public static final String SSHA_LABEL = "{SSHA}";
public static final int SSHA_DIGEST_SIZE = 20;
public static final int SSHA_SALT_SIZE = 8;
public String digestWithStoredSalt(String password, String storedDigest) {
Assert.Arg.notNull(password, "password");
Assert.Arg.notNull(storedDigest, "storedDigest");
if (!storedDigest.startsWith(SSHA_LABEL)) {
throw new UnsupportedOperationException("Unsupported algorithm.");
}
String base64Digest = storedDigest.substring(SSHA_LABEL.length());
byte[] digestWithSalt = Base64.decodeBase64(base64Digest.getBytes());
byte[] salt = new byte[SSHA_SALT_SIZE];
System.arraycopy(digestWithSalt, SSHA_DIGEST_SIZE, salt, 0, SSHA_SALT_SIZE);
return createSshaDigest(password, salt);
}
public String createSshaDigest(String password) {
Assert.Arg.notNull(password, "password");
return createSshaDigest(password, createSalt(SSHA_SALT_SIZE));
}
private String createSshaDigest(String password, byte[] salt) {
byte[] passwordWithSalt = ArrayUtils.addAll(password.getBytes(), salt);
byte[] encryptedPassword = DigestUtils.sha(passwordWithSalt);
byte[] encryptedPasswordWithSalt = ArrayUtils.addAll(encryptedPassword, salt);
String result = new String(Base64.encodeBase64(encryptedPasswordWithSalt));
return SSHA_LABEL + result;
}
private byte[] createSalt(int size) {
byte[] salt = new byte[size];
SecureRandom random;
try {
random = SecureRandom.getInstance("SHA1PRNG");
}
catch (NoSuchAlgorithmException e) {
throw new UnhandledException(e);
}
random.nextBytes(salt);
return salt;
}
}