1 package org.cacert.gigi.util;
3 import java.io.UnsupportedEncodingException;
4 import java.security.MessageDigest;
5 import java.security.NoSuchAlgorithmException;
7 import com.lambdaworks.crypto.SCryptUtil;
9 public class PasswordHash {
12 * Verifies a password hash.
15 * The password that should result in the given hash.
17 * The hash to verify the password against.
19 * <li><code>null</code>, if the password was valid</li>
20 * <li><code>hash</code>, if the password is valid and the hash
21 * doesn't need to be updated</li>
22 * <li>a new hash, if the password is valid but the hash in the
23 * database needs to be updated.</li>
26 public static String verifyHash(String password, String hash) {
27 if (password == null || password.isEmpty()) {
30 if (hash.contains("$")) {
31 if (SCryptUtil.check(password, hash)) {
37 String newhash = sha1(password);
39 if (newhash.length() != hash.length()) {
42 for (int i = 0; i < newhash.length(); i++) {
43 match &= newhash.charAt(i) == hash.charAt(i);
46 return hash(password);
52 public static String sha1(String password) {
54 MessageDigest md = MessageDigest.getInstance("SHA1");
55 byte[] digest = md.digest(password.getBytes("UTF-8"));
56 StringBuffer res = new StringBuffer(digest.length * 2);
57 for (int i = 0; i < digest.length; i++) {
58 res.append(Integer.toHexString((digest[i] & 0xF0) >> 4));
59 res.append(Integer.toHexString(digest[i] & 0xF));
61 return res.toString();
62 } catch (NoSuchAlgorithmException e) {
64 } catch (UnsupportedEncodingException e) {
69 public static String hash(String password) {
70 return SCryptUtil.scrypt(password, 1 << 14, 8, 1);