Spring安全性3.1.4和ShaPasswordEncoder弃用

Dar*_*ner 15 spring-security

今天我将我正在处理的应用程序的spring安全版本从3.1.3升级到3.1.4,我注意到了org.springframework.security.authentication.encoding.ShaPasswordEncoder类上的弃用警告.

所以我切换到了新的org.springframework.security.crypto.password.StandardPasswordEncoder实现.

我有它工作,我能够注册一个新用户并登录我的应用程序,但是,我担心,我无法使用以前的ShaPasswordEncoder和我的自定义盐生成的密码登录.

由于我有一个已经注册了许多用户的数据库,我该怎么做才能切换实现而不会使旧的编码密码失效?它甚至可能吗?

另请参见:如何使用Spring Security中的新PasswordEncoder

Sha*_*eep 18

如果您想切换到更安全的密码编码机制,那么我建议您使用BCrypt.我会使用这样的东西来迁移你的用户:

// Implement the old PasswordEncoder interface
public class MigrateUsersPasswordEncoder implements PasswordEncoder {
    @Autowired
    ShaPasswordEncoder legacyEncoder;
    @Autowired
    JdbcTemplate template;

    BCryptPasswordEncoder bcryptEncoder = new BCryptPasswordEncoder();

    @Override
    public String encodePassword(String rawPass, Object salt) {
        return bcryptEncoder.encode(rawPass);
    }

    @Override
    public boolean isPasswordValid(String encPass, String rawPass, Object salt) {
        if (legacyEncoder.isPasswordValid(encPass, rawPass, salt)) {
            template.update("update users set password = ? where password = ?", bcryptEncoder.encode(rawPass), encPass);
            return true;
        }
        return bcryptEncoder.matches(rawPass, encPass);
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以按密码字段的格式检查已迁移的用户比例.BCrypt字符串具有以$符号开头的独特语法.

其中一个答案指出此代码可能会意外地同时更新多个密码.问题表明正在使用定制盐,因此如果随机选择盐,碰撞的可能性可以忽略不计,但情况可能并非总是如此.如果更新了两个密码,问题是什么?然后可以从bcrypt哈希中检测到帐户具有相同的密码.无论如何都是这种情况,因为它要求SHA哈希值与更新相同.如果您认为这可能是一个问题(例如,由于盐选择不当或甚至使用未加盐的哈希),修改SQL以检测此问题并使用单独的BCrypt哈希值执行多个更新将是微不足道的.


tas*_*tle 5

我尝试在已接受的答案中添加评论,但可惜,我还没有足够的信誉。:(

我相信接受的答案的代码片段在更新数据库中的密码时存在潜在危险。如果 ShaPasswordEncoder 在加密时产生相同的结果(这就是为什么假设可以找到旧密码,并且我验证了这绝对是正确的,至少在 ShaPasswordEncoder 上使用空盐),您仍然无法保证密码在所有用户中是唯一的。您可能偶然与系统上的其他用户共享相同的密码,并且该 SQL 代码最终会更改碰巧拥有您密码的所有用户。

我认为最安全的策略是不更新用户的密码,而是提供计划最终删除 ShaPasswordEncoder 的迁移策略。

  • 使用提供的示例代码。
  • 删除更新数据库的代码。
  • 添加“忘记密码”或“生成新密码”等功能,以处理删除 ShaPasswordEncoder 后用户未创建新密码的最终情况。就像当您升级到 Spring Security 时将其删除一样,或者选择自己删除它。
  • 更新您的文档或明确表示在该软件的下一个主要发行版本中,用户将必须重新保存其密码或必须使用前面提到的密码重置功能。
  • 给用户一个主要版本发布周期的过渡期(他们可能不会这样做,只是陷入重置密码的困境)。