removed all checkstyle errors, updated sprint backlog
[staff/due1/sed-hs15-srs-purple.git] / src / main / java / ch / bfh / ti / srs / extern / Password.java
CommitLineData
66cc653d
D
1/*\r
2 * Copyright (c) 2015 Berner Fachhochschule, Switzerland.\r
3 *\r
4 * Project Smart Reservation System.\r
5 *\r
6 * Distributable under GPL license. See terms of license at gnu.org.\r
7 */\r
ed6d035d 8package ch.bfh.ti.srs.extern;\r
7f912ebe
M
9\r
10import javax.crypto.SecretKey;\r
11import javax.crypto.SecretKeyFactory;\r
12import javax.crypto.spec.PBEKeySpec;\r
13import java.security.SecureRandom;\r
14import org.apache.commons.codec.binary.Base64;\r
15\r
16public class Password {\r
66cc653d
D
17 // The higher the number of iterations the more\r
18 // expensive computing the hash is for us and\r
19 // also for an attacker.\r
20 private static final int iterations = 20 * 1000;\r
21 private static final int saltLen = 32;\r
22 private static final int desiredKeyLen = 256;\r
7f912ebe 23\r
66cc653d
D
24 /**\r
25 * Computes a salted PBKDF2 hash of given plaintext password suitable for\r
26 * storing in a database. Empty passwords are not supported.\r
27 */\r
28 public static String getSaltedHash(String password) throws Exception {\r
29 byte[] salt = SecureRandom.getInstance("SHA1PRNG").generateSeed(saltLen);\r
30 // store the salt with the password\r
31 return Base64.encodeBase64String(salt) + "$" + hash(password, salt);\r
32 }\r
7f912ebe 33\r
66cc653d
D
34 /**\r
35 * Checks whether given plaintext password corresponds to a stored salted\r
36 * hash of the password.\r
37 */\r
38 public static boolean check(String password, String stored) throws Exception {\r
39 String[] saltAndPass = stored.split("\\$");\r
40 if (saltAndPass.length != 2) {\r
41 throw new IllegalStateException("The stored password have the form 'salt$hash'");\r
42 }\r
43 String hashOfInput = hash(password, Base64.decodeBase64(saltAndPass[0]));\r
44 return hashOfInput.equals(saltAndPass[1]);\r
45 }\r
7f912ebe 46\r
66cc653d
D
47 // using PBKDF2 from Sun, an alternative is https://github.com/wg/scrypt\r
48 // cf. http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html\r
49 private static String hash(String password, byte[] salt) throws Exception {\r
50 if (password == null || password.length() == 0)\r
51 throw new IllegalArgumentException("Empty passwords are not supported.");\r
52 SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");\r
53 SecretKey key = f.generateSecret(new PBEKeySpec(password.toCharArray(), salt, iterations, desiredKeyLen));\r
54 return Base64.encodeBase64String(key.getEncoded());\r
55 }\r
7f912ebe 56}\r