【问题标题】:Spring Security Salt Configuration with MD5 using basic String objectSpring Security Salt Configuration with MD5 using basic String object
【发布时间】:2013-10-09 08:34:16
【问题描述】:

我检查了这个论坛和文档,但没有找到这个问题的答案,即如何使用基本的 java 对象作为 MD5 编码的盐来进行基本的 Spring Security 配置设置?

这是我的 Spring Security 上下文 sn-p 配置:

  <beans:bean id="saltSource" class="com.myproject.sec.util.MyString" scope="singleton" >
      <beans:constructor-arg value="12345" />
  </beans:bean>

  <authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <password-encoder hash="md5">
            <salt-source ref="saltSource" />
        </password-encoder>
    </authentication-provider> 
  </authentication-manager>

...但是这个配置抛出了一个不需要的错误异常抱怨盐源不是 org.springframework.security.authentication.dao.SaltSource 接口,但我不想使用用户详细信息的属性作为我的盐(因为此界面支持用户详细信息),而是我的自定义字符串对象,如上所示。我该如何做到这一点?

另外,作为第二个密切相关的问题,我知道我可以像这样将 Salt 作为用户名:

  <authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <password-encoder hash="md5">
            <salt-source user-property="username"/>
        </password-encoder>
    </authentication-provider> 
  </authentication-manager>

,有一个系统范围的固定盐“12345”,如下所示:

  <authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userService">
        <password-encoder hash="md5">
            <salt-source system-wide="12345"/>
        </password-encoder>
    </authentication-provider> 
  </authentication-manager>

...但是如何将 Salt 作为用户名和系统范围常量“12345”的串联,例如,如果用户名是 fred,则将 Salt 作为“fred12345”而不诉诸于覆盖实现我自己的编码?

【问题讨论】:

    标签: spring spring-mvc spring-security


    【解决方案1】:

    请不要使用 MD5 对密码进行哈希处理,很容易被破解。

    使用 Spring Security 的新 BCryptPasswordEncoder。它为您处理加盐(并将哈希和盐存储在同一个数据库列中):

    http://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/crypto/bcrypt/BCryptPasswordEncoder.html

    这是我的简单方法的答案:

    Spring Security with roles and permissions

    【讨论】:

    • 感谢您的信息。我打算给这个答案打勾,但我想问一下:(1)如果使用唯一的串联盐(如上所述),为什么很容易破解 MD5? (2) 如果我出于某种原因确实决定使用 MD5,是否可以(不覆盖)通过 Spring Security 配置上下文文件将唯一的 Salt(用户名 + MyString 对象)传递给 MD5,如果可以,如何?跨度>
    • 这里有一些关于破解快速哈希速度的数据:security.stackexchange.com/questions/8607/…
    【解决方案2】:

    如果你希望 salt 是用户名 + "12345",你可以实现自己的 SaltSource(很简单):

    public class UserNameAndStringSalt implements SaltSource {
        @Override
        public Object getSalt(UserDetails user) {
            return user.getUsername() + "12345";                
        }
    }
    

    然后:

    <beans:bean id="saltSource" class="com.myproject.UserNameAndStringSalt" scope="singleton" />
    
    <authentication-manager alias="authenticationManager">
      <authentication-provider user-service-ref="userService">
          <password-encoder hash="md5">
              <salt-source ref="saltSource" />
          </password-encoder>
      </authentication-provider> 
    </authentication-manager>
    

    正如 Neil McGuigan 在上面的回答中所说,尽量不要使用 MD5 或单通道 SHA - 最好使用 BCrypt 或 SCrypt,原因如下:https://security.stackexchange.com/questions/8607/how-quickly-can-these-password-schemes-really-be-beaten

    【讨论】:

    • 感谢您的帖子,但我一直在寻找如何实现这一点,而无需求助于实现自己的 Salt Source,但如果可能的话,可以通过 Spring Security 配置上下文文件来实现。
    【解决方案3】:

    推荐使用spring security提供的StandardPasswordEncoder。它会自动为您处理盐渍。它还使用更强大的 SHA256 哈希。

    http://docs.spring.io/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/crypto/password/StandardPasswordEncoder.html

    <beans:bean id="passwordEncoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder" />
    
    <authentication-manager alias="authenticationManager">
        <authentication-provider user-service-ref="userService">
            <password-encoder ref="passwordEncoder" />   
        </authentication-provider>
    </authentication-manager>
    

    【讨论】:

    • 使用 BCryptPasswordEncoder 的默认值为 10 轮,除了具有用于散列的 SecureRandom 实例外,还可以通过其构造函数轻松设置为任何数字(例如 1024)。它实现了 PasswordEncoder 接口,该接口声明它将使用 SHA-1 或更大的散列以及 8 字节或更大的随机生成的盐。使用 StandardPasswordEncoder 具有 SHA-256 哈希和 1024 次迭代和 8 字节随机盐值以及 Secret 值。那么,BCryptPasswordEncoder 使用什么哈希算法呢?这两个中哪一个更能抵御可能的黑客攻击?
    • 直到我发布答案后我才注意到@neilmcguigan。研究一下,BCryptEncoder 是更好用的一个(甚至在 StandardPasswordEncoder 的源代码中也这么说)。 BCrypt 不是哈希算法,而是key derivation function (KDF)。它在封面下使用河豚。我真正感兴趣的是 bcrypt 是自适应的。这意味着你可以在未来增加它的强度,使其破解成本更高。
    • 感谢您的澄清。
    猜你喜欢
    • 2020-09-10
    • 2020-08-09
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2015-11-17
    • 2012-01-29
    • 2015-01-07
    • 2010-11-09
    相关资源
    最近更新 更多