使用 Spring/Hibernate 进行密码加密 - Jasypt 还是其他? [关闭]

Posted

技术标签:

【中文标题】使用 Spring/Hibernate 进行密码加密 - Jasypt 还是其他? [关闭]【英文标题】:Password encryption with Spring/Hibernate - Jasypt or something else? [closed] 【发布时间】:2010-11-07 16:32:41 【问题描述】:

在数据访问层中使用 Spring 和 Hibernate (JPA) 的 Java 应用程序堆栈中,应用密码加密的好方法是什么(希望使用注释),以及在哪里可以找到有关完成它的更多信息(教程、等)?

据了解,我会使用支持 JCA 的算法来加密密码,但如果有简单的方法,我宁愿不必实现包装器逻辑。

我在看 Jasypt,并且 a) 想知道这是否是一个不错的选择以及如何去做,b) 人们还在为此使用什么。如果有人在使用 Jasypt 或替代方案,请详细说明您的体验,那就太好了。

【问题讨论】:

我一直存储密码的哈希值而不是实际密码。这样你仍然可以验证它,但你没有任何存储它的责任。 对,这正是我想要做的 - 只是试图找到一个有助于在 ORM 层上进行散列 + 查询的库。 【参考方案1】:

如果您在应用程序中使用 Spring,那么您也可以使用Spring Security,它为您提供了多个密码编码器,即ShaPasswordEncoder 你可以在***找到它

【讨论】:

【参考方案2】:

Java 已经为您提供了所有必需的库。如OWASP 所述,只需创建一个使用盐实现散列的实用方法。

如果您真的不想拥有该代码并且不介意额外的依赖,那么Shiro 库(以前的JSecurity)似乎具有 OWASP 描述的implementation。

看起来你提到的 JASYPT 库也有一个similar utility。

我意识到这个答案没有提到 Spring 或 Hibernate,但我不清楚您希望如何在这种情况下使用它们。

【讨论】:

你试图在休眠配置文件中加密数据库密码的地方?你最后是怎么做到的?我遇到了休眠 5 的问题。 @pitchblack408,这是用于隐藏应用程序数据中的密码,例如系统用户的密码,而不是用于打开数据库连接的密码。 谢谢,在阅读所有文档后我现在看到了【参考方案3】:

Jasypt 似乎没有特定于 Hibernate 的方法,但您可以在 Spring 中设置密码加密器:

  <!-- 
   Set up string digester here so we can configure it for more pools if it's a problem... 
  -->
  <bean id="stringDigester" class="org.jasypt.digest.PooledStringDigester">
    <!-- same settings as StrongPasswordGenerator -->
    <property name="poolSize" value="2"/>
    <property name="algorithm" value="SHA-256"/>
    <property name="iterations" value="100000"/>
    <property name="saltGenerator">
      <bean class="org.jasypt.salt.RandomSaltGenerator"/>
    </property>
    <property name="saltSizeBytes" value="16"/>
  </bean>

  <!-- ...and then we only have to deal with the passwordEncryptor interface in code. -->
  <bean id="passwordEncryptor" class="com.myproject.util.StringPasswordEncryptor">
    <property name="stringDigester" ref="stringDigester"/>
  </bean>

之后,调用 context.getBean("passwordEncryptor") 获取加密器,然后调用 encryptPassword() 或 checkPassword()。

【讨论】:

【参考方案4】:

如果您正在寻找什么,您可以使用Jasypt with Hibernate 即时加密或散列您的属性。如果您也想自己动手,使用 JCE 计算摘要(哈希)的实际算法非常简单。

【讨论】:

我不认为带有 Hibernate 的 JASYPT 方法非常适合密码,因为它可以解密该值。密码应该是安全的,具有单向摘要。 JASYPT 确实支持这一点 - jasypt.org/howtoencryptuserpasswords.html. 我看到了,但他们提供的 Hibernate 集成似乎没有利用它。 Hibernate 集成仅用于加密/解密,而不是单向摘要。 我对此进行了研究,laz 是正确的——休眠加密不是基于摘要的,因此不适合密码。从文档来看,Jasypt 的 StrongPasswordGenerator 似乎可以工作。【参考方案5】:

MD5 或 SHA-256 都可以,虽然 MD5 现在可以破解了。

也许我误解了这个问题,但它应该只是比较哈希密码。

在休眠状态下,只需存储为字符串。在验证方面,有一个类似的方法:

public validate(String user, String pass)

    if(getUser(user).getPass().equals(getHash(pass)))
        return true;
    return false;

【讨论】:

同样的评论,我不是在寻找要使用的架构或算法——只是人们实际使用的方式。 这是您要找的更多内容吗? evolt.org/node/60122 这描述了我现在正在做的事情 - 我想知道是否有办法注释休眠属性或自动执行此操作。看起来更干净。 我从来没有遇到过这样的事情。您可以根据注释来调整自己的 AOP 切入点,但对于这种情况来说,这似乎有点过头了。【参考方案6】:

我只是使用类似于SHA-256(username + ":" + password + ":" + salt) 的东西并将其存储在数据库中名为 passwd 的 64 个字符的列中。

***说,与盐有关:“盐数据使使用字典条目预加密的字典攻击变得复杂:使用的每一位盐都会使所需的存储量和计算量翻倍。......为了获得最佳安全性,盐值是保密,与密码数据库分开。当数据库被盗但盐没有被盗时,这提供了一个优势。"

因此,要进行身份验证,请使用提供的用户名从数据库中获取用户,然后使用通过登录尝试提供的密码生成相同的哈希,并与数据库中的密码进行比较。还为登录尝试添加一些速率限制(例如,每 5 分钟 5 次)。如果用户忘记了密码,切勿将密码通过电子邮件发送给他们(因为您不会将其存储),也不要通过电子邮件向他们发送新生成的密码,而是通过电子邮件向他们发送链接以使用更改密码密钥/nonce/salt 更改密码您可以检查的 URL。

【讨论】:

我编辑了我的问题 - 我不是在寻找算法,而是在寻找一种标准(即库实现)方法来使用带有 Spring/Hibernate 堆栈的 JCA 算法。 所以你真的需要像 @Password("SHA-256") 在你的用户账户模型中的一个字段上注释,并让你的框架自动处理验证在后台?在某些时候,您开始要求框架在功能方面过于具体,并牺牲灵活性。

以上是关于使用 Spring/Hibernate 进行密码加密 - Jasypt 还是其他? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用 H2 DB 进行 Spring/Hibernate 集成测试

SpringMVC+Spring+Hibernate个人家庭财务管理系统

如何使用 Spring + Hibernate 对实体进行自定义验证以进行多租户设置

使用 Spring 3 和 Hibernate 3 进行身份验证(基于注释)

spring mvc+spring + hibernate 整合

Spring Hibernate Validation