如何将密码文本与bcrypt散列进行比较?

时间:2019-02-08 17:28:28

标签: spring spring-boot spring-security cryptography bcrypt

嗨,我的应用程序中有一个用例,该用例应防止用户在重置密码时选择其后三个密码之一。我在前端使用angular ui,在后端使用spring boot。在我的情况下,用户密码存储为bcrypt哈希。以下是spring安全配置。

  @Configuration
    @Import(SecurityProblemSupport.class)
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

        @PostConstruct
        public void init() {
            try {
                authenticationManagerBuilder
                    .userDetailsService(userDetailsService)
                    .passwordEncoder(passwordEncoder());
            } catch (Exception e) {
                throw new BeanInitializationException("Security configuration failed", e);
            }
        }
       @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

所以我可以将用户使用的最后3个密码存储为bcrypt哈希。

但是我该如何比较用户输入的密码和最近存储的3个bcrypt密码。 就我而言,当我运行以下代码片段示例

BCryptPasswordEncoder b = new BCryptPasswordEncoder();

    for(int i =0;i<10;i++) {
        System.out.println(b.encode("passw0rd"));

    }

它生成以下bcrypt哈希。每个哈希都是不同的,这是合理的,因为当我检查org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder时,我可以看到生成的盐是随机值。

$2a$10$tztZsPFZ.T.82Gl/VIuMt.RDjayTwuMLAkRkO9SB.rd92vHWKZmRm
$2a$10$yTHyWDmcCBq3OSPOxjj4TuW9qXYE31CU.fFlWxppii9AizL0lKMzO
$2a$10$Z6aVwg.FNq/2I4zmDjDOceT9ha0Ur/UKsCfdADLvNHiZpR7Sz53fC
$2a$10$yKDVeOUvfTQuTnCHGJp.LeURFcXK6JcHB6lrSgoX1pRjxXDoc8up.
$2a$10$ZuAL06GS7shHz.U/ywb2iuhv2Spubl7Xo4NZ7QOYw3cHWK7/7ZKcC
$2a$10$4T37YehBTmPWuN9j.ga2XeF9GHy6EWDhQS5Uc9bHvJTK8.xIm1coS
$2a$10$o/zxjGkArT7YdDkrk5Qer.oJbZAYpJW39iWAWFqbOhpTf3FmyfWRC
$2a$10$eo7yuuE2f7XqJL8Wjyz.F.xj78ltWuMS1P0O/I6X7iNPwdsWMVzu6
$2a$10$3ErH2GtZpYJGg1BhfgcO/uOt/L2wYg4RoO8.fNRam458WWdymdQLW
$2a$10$IksOJvL/a0ebl4R2/nbMQ.XmjNARIzNo8.aLXiTFs1Pxd06SsnOWa

因此,如果用户从用户界面以我的重置形式输入“ passw0rd”,将如何与最后3个bcrypt哈希值进行比较。换句话说,如果我为“ passw0rd”生成bcrypt,它将始终是一个新值,并且与数据库中存储的值不匹配。

请帮助 谢谢

3 个答案:

答案 0 :(得分:4)

您可以在BCryptPasswordEncoder中使用match方法,如下所示:

b.matches("passw0rd", hash)

答案 1 :(得分:1)

实际上我找到了答案。 我意识到我可以使用org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder类中存在的匹配函数。

System.out.println(b.matches(“ passw0rd”,“ $ 2a $ 10 $ tztZsPFZ.T.82Gl / VIuMt.RDjayTwuMLAkRkO9SB.rd92vHWKZmRm”));

答案 2 :(得分:1)

@Sumon Bappi :Spring Security 只是从先前生成的散列中读取盐并使用相同的盐再次重新散列输入的密码。它比较了两个最终的哈希值,显然它是相同的。

例如: 密码:测试, 哈希:$2a$10$nCgoWdqJwQs9prt7X5a/2eWLn88I8pon6iNat90u4rq4mHqtoPGQy

Hash 有 3 个段,每个段由 $ 符号分隔。 2a 是 bcript 的版本,10 是总轮数,nCgoWdqJwQs9prt7X5a/2e 是盐。

因此,spring security 使用密码(“test”)和盐(“nCgoWdqJwQs9prt7X5a/2e”)并运行散列。显然它生成与密码和盐匹配相​​同的哈希