user4143467
user4143467

Reputation:

how to encrypt password using spring hibernate in java

So my problem is this, I have a jsp that has a register button on every navigation page,And i want to encrypt my password using spring and hibernate,but unfortunately i don't know how.. even using spring and hibernate i don't actually get how it works. and also i have a Encryption class i am thinking about encrypting it inside my Users class but i know when logging in it will cause a problem... here is my code by the way

code in controller

@Controller
@RequestMapping("/ecomplain")
public class ComplainController 
{
  @Autowired
  private UserService userService;
  @Autowired
  private ComplainService complainService;

  @RequestMapping(value = "/Homepage")
  public String showHomepage(Map<String, Object> map) 
 {
   map.put("users", new Users());
   return "/ecomplain/Homepage";
 }

 @RequestMapping(value = "/ComplaintForm")
 public String showComplainForm(Map<String, Object> map) 
 {
   map.put("users", new Users());
   map.put("complains", new Complains());
   return "/ecomplain/ComplaintForm";
 }

 @RequestMapping(value = "/CrimeForum")
 public String showCrimeForum(Map<String, Object> map) 
 {
    map.put("users", new Users());
    map.put("complains", new Complains());
    map.put("complainList", complainService.listComplains());
    return "/ecomplain/CrimeForum";
 }

 @RequestMapping(value = "/About")
 public String showAbout(Map<String, Object> map) 
 {
    map.put("users", new Users());
    return "/ecomplain/About";
 }

 @RequestMapping("/get/{userId}")
 public String getUsers(@PathVariable Long userId, Map<String, Object> map) 
 {
   Users users = userService.getUsers(userId);
   map.put("users", users);

   return "/ecomplain/CreateUserForm";
 }

 @RequestMapping("/getComplain/{complainId}")
 public String getComplains(@PathVariable Long complainId, Map<String, Object> map) 
 {
   Complains complains = complainService.getComplains(complainId);
   map.put("complains", complains);

   return "/ecomplain/ComplainDetails";
 }

 @RequestMapping(value = "/save", method = RequestMethod.POST)
 public String saveUsers(@ModelAttribute("users") Users users, BindingResult result)
 {
   userService.saveUsers(users);
   return "redirect:listBooks";
 }

 @RequestMapping(value = "/savecomplain", method = RequestMethod.POST)
 public String saveComplains(@ModelAttribute("complains") Complains complains, BindingResult result) 
 {
   complainService.saveComplains(complains);
   return "redirect:ComplaintForm";
 }

 @RequestMapping("/delete/{userId}")
 public String deleteUsers(@PathVariable("userId") Long userId) 
 {
   userService.deleteUsers(userId);
   return "redirect:/ecomplain/Homepage";
 }

 @RequestMapping("/delete/{complainId}")
 public String deleteComplains(@PathVariable("complainId") Long complainId) 
 {
   complainService.deleteComplains(complainId);
   return "redirect:/ecomplain/Homepage";
 }
}

Users class

@Entity
@Table(name = "users")
public class Users
{
  private Long userId;
  private String email;
  private String username;
  private String password;
  private String location;

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  public Long getUserId() 
 {
    return userId;
 }

 @Column(nullable = false)
 public String getEmail() 
 {
    return email;
 }

 @Column(nullable = false, unique = true)
 public String getUsername() 
 {
    return username;
 }

 @Column(nullable = false)
 public String getPassword() 
 {
    return password;
 } 

 @Column(nullable = false)
 public String getLocation() 
 {
    return location;
 }

 public void setUserId(Long userId) 
 {
    this.userId = userId;
 }

 public void setEmail(String email) 
 {
    this.email = email;
 }

 public void setUsername(String username) 
 {
    this.username = username;
 }

 public void setPassword(String password)
 {
    this.password = password;
 }

 public void setLocation(String location)
 {
    this.location = location;
 }
}

UsersDao

public interface UsersDao 
{
  public void saveUsers(Users users);
  public List<Users> listUsers();
  public Users getUsers(Long userId);
  public void deleteUsers(Long userId);
}

UsersDaoImpl

@Repository
public class UsersDaoImpl implements UsersDao 
{
  @Autowired
  private SessionFactory sessionFactory;

  public void saveUsers(Users users) 
  {
     getSession().merge(users);
  }

  public List<Users> listUsers() 
  {
    return getSession().createCriteria(Users.class).list();
  }

  public Users getUsers(Long userId) 
  {
     return (Users) getSession().get(Users.class, userId);
  }

  public void deleteUsers(Long userId) 
  {
    Users users = getUsers(userId);

    if (null != users) 
    {
       getSession().delete(users);
    }
  }

  private Session getSession() 
  {
     Session sess = getSessionFactory().getCurrentSession();
     if (sess == null) 
     {
       sess = getSessionFactory().openSession();
     }
     return sess;
  }

  private SessionFactory getSessionFactory() 
 {
    return sessionFactory;
 }
}

and here is my Encryption class that i want to use

public class Encryption 
{
   public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";

   public static final int SALT_BYTE_SIZE = 24;
   public static final int HASH_BYTE_SIZE = 24;
   public static final int PBKDF2_ITERATIONS = 1000;

   public static final int ITERATION_INDEX = 0;
   public static final int SALT_INDEX = 1;
   public static final int PBKDF2_INDEX = 2;

   public static String createHash(String password) throws NoSuchAlgorithmException,      InvalidKeySpecException
   {
     return createHash(password.toCharArray());
   }

  public static String createHash(char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException
  {

     SecureRandom random = new SecureRandom();
     byte[] salt = new byte[SALT_BYTE_SIZE];
     random.nextBytes(salt);
     byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);
     return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" +  toHex(hash);
  }


  public static boolean validatePassword(String password, String correctHash) throws  NoSuchAlgorithmException, InvalidKeySpecException
  {
     return validatePassword(password.toCharArray(), correctHash);
  }

  public static boolean validatePassword(char[] password, String correctHash) throws NoSuchAlgorithmException, InvalidKeySpecException
  {
     String[] params = correctHash.split(":");
     int iterations = Integer.parseInt(params[ITERATION_INDEX]);
     byte[] salt = fromHex(params[SALT_INDEX]);
     byte[] hash = fromHex(params[PBKDF2_INDEX]);   
     byte[] testHash = pbkdf2(password, salt, iterations, hash.length);
     return slowEquals(hash, testHash);
  }

  private static boolean slowEquals(byte[] a, byte[] b)
  {
     int diff = a.length ^ b.length;
     for(int i = 0; i < a.length && i < b.length; i++)
        diff |= a[i] ^ b[i];
     return diff == 0;
  }

  private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes) throws NoSuchAlgorithmException, InvalidKeySpecException
  {
     PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);
     SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
     return skf.generateSecret(spec).getEncoded();
  }

  private static byte[] fromHex(String hex)
  {
     byte[] binary = new byte[hex.length() / 2];
     for(int i = 0; i < binary.length; i++)
     {
        binary[i] = (byte)Integer.parseInt(hex.substring(2*i, 2*i+2), 16);
     }
     return binary;
  }

  private static String toHex(byte[] array)
  {
    BigInteger bi = new BigInteger(1, array);
    String hex = bi.toString(16);
    int paddingLength = (array.length * 2) - hex.length();
    if(paddingLength > 0) 
       return String.format("%0" + paddingLength + "d", 0) + hex;
    else
       return hex;
  }

  public String saltedPass(String password) 
  {
     String hash = "";
      try 
      {
         hash = createHash(password);
      } 

      catch (NoSuchAlgorithmException e) 
      {
         e.printStackTrace();
      } 

      catch (InvalidKeySpecException e) 
      {
         e.printStackTrace();
      }
      return hash;
  }

  public boolean validation(String password, String hash) 
  {
      try 
      {
          if (validatePassword(password, hash)) 
          {
            System.out.println("CORRECT PASSWORD!");
            return true;
          }
      }  

      catch (Exception ex) 
      {
          System.out.println("ERROR: " + ex);
      }
      return false;
  }
}

i hope someone can help me.. even a small idea can help me

Upvotes: 0

Views: 8818

Answers (3)

Wim Deblauwe
Wim Deblauwe

Reputation: 26858

The recommended way for Spring Security is to use the BCryptPasswordEncoder. See http://www.baeldung.com/spring-security-registration-password-encoding-bcrypt for more details.

Basically, you use an instance of BCryptPasswordEncoder to encrypt the password before you store it in the database.

Upvotes: 0

Haochen Xie
Haochen Xie

Reputation: 390

Here's an example: https://gist.github.com/haochenx/28283eb950c8dc6bbaf7

The core lines are:

public static String encryptPassphrase(String passphrase) {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");

        byte[] salt = new byte[18];
        RNG.nextBytes(salt);

        md.update(salt);
        md.update(passphrase.getBytes(StandardCharsets.UTF_8));

        byte[] passEnc = md.digest();
        return String.format("%s$%s",
                new String(Base64.encode(salt)),
                new String(Base64.encode(passEnc)));
    } catch (NoSuchAlgorithmException ex) {
        throw new RuntimeException(ex);     // this should never happen though
    }
}

public static boolean verifyPassphrase(String passphrase, String encryptedPassphrase) {
    String[] splited = encryptedPassphrase.split("\\$");
    byte[] salt = Base64.decode(splited[0].getBytes());
    byte[] passEncDb = Base64.decode(splited[1].getBytes());

    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");

        md.update(salt);
        md.update(passphrase.getBytes(StandardCharsets.UTF_8));
        byte[] passEnc = md.digest();

        return Arrays.equals(passEncDb, passEnc);
    } catch (NoSuchAlgorithmException ex) {
        throw new RuntimeException(ex);     // this should never happen though
    }
}

Please note that @Darshan's approach has a couple of security problems. Firstly, hashing password without salt will defer the security. Secondly, MD5 is not considered secure any more, so usage in new application is not recommended. Lastly, not a security problem actually, but when getting byte[] from a String, you should always specify a charset unless you are sure there's only ASCII characters (not even true exactly, but practically, yes) or you will run into problem when you deploy the application into different servers.

I have only included a very basic test in the main method, and the class is only for your reference. I also haven't done argument checking, which should be added in production.

Upvotes: 2

Darshan Lila
Darshan Lila

Reputation: 5868

You can use MessageDigest.
Try following:

MessageDigest digest=MessageDigest.getInstance("MD5");
String test="test";
digest.update(test.getBytes());
byte hash[]=digest.digest();

Upvotes: 0

Related Questions