Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.registryKit.user; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.util.Arrays; import java.util.List; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import javax.transaction.Transactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * * @author chadmccue */ @Service public class userManager { @Autowired private userDAO userDAO; @Transactional public User getUserByEmail(String emailAddress) { return userDAO.getUserByEmail(emailAddress); } @Transactional public void setLastLogin(String emailAddress) { userDAO.setLastLogin(emailAddress); } @Transactional public User getUserById(int userId) { return userDAO.getUserById(userId); } @Transactional public Integer getUserByIdentifier(String identifier) { return userDAO.getUserByIdentifier(identifier); } @Transactional public void updateUser(User user) { userDAO.updateUser(user); } @Transactional public List<userProgramModules> getUsedModulesByUser(Integer programId, Integer userId, Integer roleId) throws Exception { return userDAO.getUsedModulesByUser(programId, userId, roleId); } public boolean authenticate(String attemptedPassword, byte[] encryptedPassword, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { // Encrypt the clear-text password using the same salt that was used to // encrypt the original password byte[] encryptedAttemptedPassword = getEncryptedPassword(attemptedPassword, salt); // Authentication succeeds if encrypted password that the user entered // is equal to the stored hash return Arrays.equals(encryptedPassword, encryptedAttemptedPassword); } @Transactional public List<String> getUserRoles(User user) throws Exception { return userDAO.getUserRoles(user); } public byte[] getEncryptedPassword(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException { // PBKDF2 with SHA-1 as the hashing algorithm. Note that the NIST // specifically names SHA-1 as an acceptable hashing algorithm for PBKDF2 String algorithm = "PBKDF2WithHmacSHA1"; // SHA-1 generates 160 bit hashes, so that's what makes sense here int derivedKeyLength = 160; // Pick an iteration count that works for you. The NIST recommends at // least 1,000 iterations: // http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf // iOS 4.x reportedly uses 10,000: // http://blog.crackpassword.com/2010/09/smartphone-forensics-cracking-blackberry-backup-passwords/ int iterations = 20000; // byte[] b = string.getBytes(Charset.forName("UTF-8")); KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, derivedKeyLength); SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm); return f.generateSecret(spec).getEncoded(); } @Transactional public User getUserByResetCode(String resetCode) { return userDAO.getUserByResetCode(resetCode); } public User encryptPW(User user) throws Exception { //first we get salt byte[] salt = generateSalt(); user.setRandomSalt(salt); byte[] encPW = getEncryptedPassword(user.getPassword(), salt); user.setEncryptedPw(encPW); // then we encrypt and send back pw return user; } public byte[] generateSalt() throws NoSuchAlgorithmException { // VERY important to use SecureRandom instead of just Random SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); // Generate a 8 byte (64 bit) salt as recommended by RSA PKCS5 byte[] salt = new byte[8]; random.nextBytes(salt); return salt; } }