从 Spring Security 5.x Bcrypt 哈希迁移到 Quarkus

Pau*_*aul 1 bcrypt quarkus

我正在尝试重写最初使用 Spring 开发的应用程序。用户身份验证是通过 Spring Security 提供的,Spring Security 使用 Bcrypt 来生成和检查散列密码。

它们以如下所示的格式存储在数据库中。据我所知,它是这样表示的:

|  |RR|        Salt          |      Hashed Password        |
$2a$10$Dh23I3CO6l1n3mOofdazreNLg2OHxzDrxyGGZEstTbITKs.cX3N/u
Run Code Online (Sandbox Code Playgroud)

(其中RR是轮数)

我尝试将其迁移到新的表结构,如使用 4.6的哈希密码表示形式下的“表 3. 示例表”中所示。组件文档,例如:

NAME | PASSWORD                        | SALT                   |ITERATION_COUNT|
=====|=================================|========================|===============|
test | NLg2OHxzDrxyGGZEstTbITKs.cX3N/u | Dh23I3CO6l1n3mOofdazre | 10            |
Run Code Online (Sandbox Code Playgroud)

我已经配置了映射器,application.properties如下所示:

quarkus.security.jdbc.principal-query.sql=SELECT u.password, u.salt, u.iteration_count FROM test_user u WHERE u.name=?
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.enabled=true
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.password-index=1
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.hash-encoding=base64
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.salt-index=2
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.salt-encoding=base64
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.iteration-count-index=3
Run Code Online (Sandbox Code Playgroud)

但是,我要么收到由无效的 base64 字符引起的错误(这并不完全令人惊讶,因为 Spring Security 中的实现声明它不是 MIME 兼容的 base64 实现),或者当该错误不存在时,它无法验证密码。

我如何才能将所有用户迁移到 Quarkus 使用的 Bcrypt 实现?

Pau*_*aul 6

所以我根本不需要拆分salt、hash和iteration count 。您可以继续使用当前的“单字符串”格式。诀窍是按如下方式配置映射器(请注意-1和salt属性iteration-count):

quarkus.security.jdbc.principal-query.bcrypt-password-mapper.enabled=true
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.password-index=1
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.salt-index=-1
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.iteration-count-index=-1
Run Code Online (Sandbox Code Playgroud)

虽然我没有在Wildfly Elytron文档或Quarkus配置文档中看到它,但它已经得到了明确的处理(请参阅GitHub 上的PasswordKeyMapper.java)

该逻辑适用于这两个属性设置为 时的情况-1。然后它解析完整的字符串并成功验证密码。