如何使用ShaPasswordEncoder正确编码密码?

时间:2013-09-06 08:30:33

标签: java spring hash spring-security sha

我想在 Spring 应用中使用ShaPasswordEncoder对密码进行编码。

ShaPasswordEncoder sha = new ShaPasswordEncoder(256);
sha.setIterations(1000);
String hash = sha.encodePassword(password, salt);

但我不应该对salt param提出什么。它可以是静态短语(例如 sT4t1cPhr453 ),还是每个用户不同的动态字符串(例如用户名或用户ID)?

编辑:

我是用户自定义AuthenticationProvider,因此我的安全上下文如下所示:

<authentication-manager>
   <authentication-provider ref="customAuthenticationProvider" />
</authentication-manager>

<beans:bean id="customAuthenticationProvider" class="com.app.cloud.auth.CustomAuthenticationProvider">

@Component("customAuthenticationProvider")
public class CustomAuthenticationProvider implements org.springframework.security.authentication.AuthenticationProvider {

    @Autowired
    private AuthService authService;

    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException,BadCredentialsException {
    //...
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}

2 个答案:

答案 0 :(得分:12)

如果您想明确定义盐,可以定义盐源:

动态盐(基于用户名属性)

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

静态盐

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="userDetailsService">
        <password-encoder hash="sha-256">
            <salt-source system-wide="MySalt" />
        </password-encoder>
    </authentication-provider>
</authentication-manager>

推荐方法

如果您使用的是Spring Security 3.1,建议的方法是使用bcrypt,这会自动生成一个盐并连接它。

<beans:bean id='bCryptPasswordEncoder' class='org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder'/>

<authentication-manager>
  <authentication-provider user-service-ref="userDetailsService">
          <password-encoder ref="bCryptPasswordEncoder"/>
  </authentication-provider>
</authentication-manager>

您可以像这样生成用户密码:

String password = "p4ssword";
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String encodedPassword = passwordEncoder.encode(password);

答案 1 :(得分:2)

盐腌哈希背后的原则是你不容易受彩虹表的影响。如果您使用静态盐,则可能(但价格昂贵)某人为您的盐构建彩虹表。如果选择很甜,有人会这样做。

理想情况下,您的salt应该是随机的(例如,使用来自SecureRandom的字节),并且每个用户应该是不同的。您应该将盐与散列密码一起存储,例如,如果您使用数据库表,那么只需要一个盐柱。

最新版本的Spring Security(3.1及更高版本)尝试以自动,透明的方式处理salt。密码编码器将自动生成随机盐并将其附加到散列而不是单独存储(例如,在不同的列中)。因为哈希和盐具有固定的长度,所以很容易确定哪个部分的数据是哪个。