]> WPIA git - gigi.git/blob - src/org/cacert/gigi/util/PasswordHash.java
Update notes about password security
[gigi.git] / src / org / cacert / gigi / util / PasswordHash.java
1 package org.cacert.gigi.util;
2
3 import java.io.UnsupportedEncodingException;
4 import java.security.MessageDigest;
5 import java.security.NoSuchAlgorithmException;
6
7 import com.lambdaworks.crypto.SCryptUtil;
8
9 public class PasswordHash {
10
11     /**
12      * Verifies a password hash.
13      * 
14      * @param password
15      *            The password that should result in the given hash.
16      * @param hash
17      *            The hash to verify the password against.
18      * @return <ul>
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>
24      *         </ul>
25      */
26     public static String verifyHash(String password, String hash) {
27         if (password == null || password.isEmpty()) {
28             return null;
29         }
30         if (hash.contains("$")) {
31             if (SCryptUtil.check(password, hash)) {
32                 return hash;
33             } else {
34                 return null;
35             }
36         }
37         String newhash = sha1(password);
38         boolean match = true;
39         if (newhash.length() != hash.length()) {
40             match = false;
41         }
42         for (int i = 0; i < newhash.length(); i++) {
43             match &= newhash.charAt(i) == hash.charAt(i);
44         }
45         if (match) {
46             return hash(password);
47         } else {
48             return null;
49         }
50     }
51
52     public static String sha1(String password) {
53         try {
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));
60             }
61             return res.toString();
62         } catch (NoSuchAlgorithmException e) {
63             throw new Error(e);
64         } catch (UnsupportedEncodingException e) {
65             throw new Error(e);
66         }
67     }
68
69     public static String hash(String password) {
70         return SCryptUtil.scrypt(password, 1 << 14, 8, 1);
71     }
72 }