【发布时间】:2015-04-09 20:04:46
【问题描述】:
我正在尝试保护我正在构建的 Web 应用程序的密码。我对密码学很陌生。我正在使用 Java 和 Sha-1 Hash 将密码存储在 Db 中。
在对此事进行一些研究之后,使用盐似乎是散列密码的最佳方法,但当然盐必须与密码一起存储。
在我的例子中,我使用数据库中的一个新列作为盐,我不知道这是否是正确的方法。如果有人窃取了我的数据库,用哈希和盐就能读取密码?在哈希和盐之间放置一个分隔符并将它们存储在一起会更好吗?在这种情况下,要检查密码的有效性,我必须解析字符串。 只是我想知道您的意见和可以在这里应用的最佳做法。
非常感谢您!
@Entity
@Table(name="USERS")
public class User implements BasePersistentEntity<Long> {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;
@Column(name="EMAIL",nullable=false,length=50,insertable=true,updatable=true)
private String email;
@Column(name="PASSWORD",nullable=false,length=40,insertable=true,updatable=true)
private String password;
@Column(name="SALT",nullable=false,length=40,insertable=true,updatable=true)
private String passwordSalt;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email=email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
if (password.equals(this.password))
{
return;
}
if (passwordSalt == null || passwordSalt.equals(""))
{
passwordSalt = RandomStringUtils.randomAscii(20);
}
this.password = DigestUtils.sha1Hex(password + passwordSalt);
}
/**
* Check if a given password is correct.
*
* @param givenPassword
* @return True is correct, else false.
*/
public boolean checkPassword(String givenPassword)
{
return (password.equals(DigestUtils.sha1Hex(givenPassword + passwordSalt)));
}
public String getPasswordSalt() {
return passwordSalt;
}
public void setPasswordSalt(String passwordSalt) {
this.passwordSalt = passwordSalt;
}
}
【问题讨论】:
-
SHA1 不安全。使用 scrypt 或 bcrypt 或 PBKDFv2。
-
另外,您在这里至少有两个不同的问题 - “如果有人用盐窃取了我的数据库,他们可以读取密码吗?” (可能更适合security.se)和“我应该添加一个新列,还是将两个内容存储在一个由
|分隔的列中?”
标签: java encryption hash cryptography sha