/** * */ package org.sinnlabs.dbvim.security; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.sql.SQLException; import java.util.Arrays; import org.apache.commons.lang3.StringUtils; import org.sinnlabs.dbvim.config.ConfigLoader; import org.sinnlabs.dbvim.model.User; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * Class manages operations with users (create, password check) * * @author peter.liverovsky * */ public class LoginProvider { /** * Check the user credentials * @param username User name to be checked * @param passwd Password to be checked * @return True if credentials is valid. * @throws SQLException * @throws IOException * @throws NoSuchAlgorithmException */ public static boolean checkCredantials(String username, String passwd) throws SQLException, IOException, NoSuchAlgorithmException { User usr = ConfigLoader.getInstance().getUsers() .queryForId(username.toLowerCase()); // user does not exist if (usr == null) return false; // password does not exist if (usr.getPassword_hash() == null || usr.getSalt() == null) return false; byte[] bDigest = base64ToByte(usr.getPassword_hash()); byte[] bSalt = base64ToByte(usr.getSalt()); // Compute new digest byte[] proposedDigest = getHash(passwd, bSalt); return Arrays.equals(proposedDigest, bDigest); } /** * From a password and a salt, returns the corresponding digest * * @param password * password to be hashed * @param salt * password salt * @return byte[] Digested password * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static byte[] getHash(String password, byte[] salt) throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.reset(); // Add password bytes to digest digest.update(salt); // Get the hash's bytes byte[] hash = digest.digest(password.getBytes("UTF-8")); return hash; } /** * From a base 64 representation, returns the corresponding byte[] * * @param data * String The base64 representation * @return byte[] * @throws IOException */ public static byte[] base64ToByte(String data) throws IOException { BASE64Decoder decoder = new BASE64Decoder(); return decoder.decodeBuffer(data); } /** * From a byte[] returns a base 64 representation * * @param data * byte[] * @return String * @throws IOException */ public static String byteToBase64(byte[] data) { BASE64Encoder endecoder = new BASE64Encoder(); return endecoder.encode(data); } /** * Creates new user * @param login User name * @param passwd User password * @return null if user already exists, otherwise new User object. * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static User createUser(String login, String passwd) throws NoSuchAlgorithmException, UnsupportedEncodingException { if (StringUtils.isBlank(login) || StringUtils.isBlank(passwd)) { throw new IllegalArgumentException("User name or password can not be empty."); } // uses a secure random SecureRandom rand = SecureRandom.getInstance("SHA1PRNG"); // Salt generation 512 bits long byte[] bSalt = new byte[64]; rand.nextBytes(bSalt); byte[] hash = getHash(passwd, bSalt); User usr = new User(login.toLowerCase().trim()); usr.setPassword_hash(byteToBase64(hash)); usr.setSalt(byteToBase64(bSalt)); usr.setEnabled(true); return usr; } /** * Updates the users password * @param user User that needs to be updated * @param newPassword new user password * @return Updated user object * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static User updatePassword(User user, String newPassword) throws NoSuchAlgorithmException, UnsupportedEncodingException { if (StringUtils.isBlank(newPassword)) { throw new IllegalArgumentException("User name or password can not be empty."); } // uses a secure random SecureRandom rand = SecureRandom.getInstance("SHA1PRNG"); // Salt generation 512 bits long byte[] bSalt = new byte[64]; rand.nextBytes(bSalt); byte[] hash = getHash(newPassword, bSalt); user.setPassword_hash(byteToBase64(hash)); user.setSalt(byteToBase64(bSalt)); return user; } }