001package usecase.auth; 002 003import javax.crypto.SecretKeyFactory; 004import javax.crypto.spec.PBEKeySpec; 005import java.io.Serializable; 006import java.security.NoSuchAlgorithmException; 007import java.security.SecureRandom; 008import java.security.spec.InvalidKeySpecException; 009import java.security.spec.KeySpec; 010import java.util.Arrays; 011 012/** 013 * Classe dedicata alla sicurezza delle password. 014 */ 015public class Pbkdf2PasswordHash implements Serializable { 016 public HashedPassword generate(String password, byte[] salt){ 017 try { 018 KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128); 019 SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 020 byte[] hash = factory.generateSecret(spec).getEncoded(); 021 022 return new HashedPassword(hash, salt); 023 } catch (InvalidKeySpecException | NoSuchAlgorithmException e) { 024 throw new RuntimeException(e); 025 } 026 } 027 028 public HashedPassword generate(String password){ 029 return generate(password, generateSalt()); 030 } 031 032 public boolean verify(String password, byte[] hashedPassword, byte[] salt){ 033 return verify(password, new HashedPassword(hashedPassword, salt)); 034 } 035 036 public boolean verify(String password, HashedPassword hashedPassword){ 037 return hashedPassword.equals(generate(password, hashedPassword.getSalt())); 038 } 039 040 private static byte[] generateSalt(){ 041 SecureRandom ss = new SecureRandom(); 042 byte[] salt = new byte[16]; 043 ss.nextBytes(salt); 044 return salt; 045 } 046 047 public static class HashedPassword{ 048 private byte[] password; 049 private byte[] salt; 050 051 private HashedPassword(byte[] password, byte[] salt) { 052 this.password = password; 053 this.salt = salt; 054 } 055 056 public byte[] getPassword() { 057 return password; 058 } 059 060 public byte[] getSalt() { 061 return salt; 062 } 063 064 @Override 065 public boolean equals(Object o) { 066 if (this == o) return true; 067 if (o == null || getClass() != o.getClass()) return false; 068 HashedPassword that = (HashedPassword) o; 069 return Arrays.equals(password, that.password) && Arrays.equals(salt, that.salt); 070 } 071 } 072}