如何在java中使用spring hibernate加密密码

时间:2014-12-27 12:02:44

标签: java spring hibernate spring-mvc encryption

所以我的问题是这个,我有一个jsp,每个导航页面都有一个注册按钮,我想用spring和hibernate加密我的密码,但不幸的是我不知道怎么做..即使使用spring和hibernate我实际上并没有得到它的工作原理。我还有一个加密类,我正在考虑在我的Users类中加密它,但我知道登录时会导致问题......顺便说一句,这是我的代码

控制器中的

代码

@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";
 }
}

用户类

@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;
 }
}

这是我想要使用的加密类

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;
  }
}

我希望有人可以帮助我......即使是一个小小的想法也可以帮助我

3 个答案:

答案 0 :(得分:0)

您可以使用 MessageDigest 请尝试以下方法:

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

答案 1 :(得分:0)

以下是一个例子:https://gist.github.com/haochenx/28283eb950c8dc6bbaf7

核心线是:

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
    }
}

请注意,@Darshan's approach存在一些安全问题。首先,没有盐的散列密码会推迟安全性。其次,MD5不再被认为是安全的,因此不建议在新应用程序中使用。最后,实际上不是安全问题,但是当从String中获取byte []时,除非您确定只有ASCII字符(确实不是真的,但实际上是,是),否则应该始终指定一个字符集,否则您将将应用程序部署到不同的服务器时遇到问题。

我只在main方法中包含了一个非常基本的测试,该类仅供您参考。我还没有完成参数检查,这应该在生产中添加。

答案 2 :(得分:0)

Spring Security的推荐方法是使用BCryptPasswordEncoder。有关详细信息,请参阅http://www.baeldung.com/spring-security-registration-password-encoding-bcrypt

基本上,在将密码存储到数据库之前,您使用BCryptPasswordEncoder的实例来加密密码。