我们目前正在将应用程序从 payara 迁移到 Quarkus,但 bCrypt 映射器遇到问题。
我们无法正确生成正确的哈希值,因为我们不知道使用的是哪个版本的 bCrypt。我们尝试使用您的 github 中的示例哈希值这工作得很好,但是当我们尝试使用我们自己生成的哈希值时,它就不行了。
我们尝试使用多个在线生成器,但我们无法找出 Quarkus 中使用的是哪个版本。然后我们尝试使用 Wildfly 生成器代码片段(见下文),因为我们认为它会使用与 quarkus 相同的算法,但这也不起作用。
static final Provider ELYTRON_PROVIDER = new WildFlyElytronProvider();
static final String TEST_PASSWORD = "test";
public static void main(String[] args) {
PasswordFactory passwordFactory = null;
try {
passwordFactory = PasswordFactory.getInstance(BCryptPassword.ALGORITHM_BCRYPT, ELYTRON_PROVIDER);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
int iterationCount = 10;
byte[] salt = new byte[BCryptPassword.BCRYPT_SALT_SIZE];
SecureRandom random = new SecureRandom();
random.nextBytes(salt);
IteratedSaltedPasswordAlgorithmSpec iteratedAlgorithmSpec = new IteratedSaltedPasswordAlgorithmSpec(iterationCount, salt);
EncryptablePasswordSpec encryptableSpec = new EncryptablePasswordSpec(TEST_PASSWORD.toCharArray(), iteratedAlgorithmSpec);
BCryptPassword original = null;
try {
original = (BCryptPassword) passwordFactory.generatePassword(encryptableSpec);
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
byte[] hash = original.getHash();
Base64.Encoder encoder = Base64.getEncoder();
System.out.println("Encoded Salt = " + encoder.encodeToString(salt));
System.out.println("Encoded Hash = " + encoder.encodeToString(hash));
}
当我们从 bCrypt 切换到 Clear 时,它也可以正常工作,这意味着数据库可以正常工作。 由于示例哈希工作正常,我们认为配置没有错误,但这里是我们的配置,以防万一:
# h2 datasource
#quarkus.datasource.url = jdbc:h2:mem:test
#quarkus.datasource.driver = org.h2.Driver
#quarkus.datasource.username = sa
#quarkus.datasource.password =
# postgres configuration
quarkus.datasource.url = jdbc:postgresql://localhost:5432/postgres
quarkus.datasource.driver = org.postgresql.Driver
quarkus.datasource.username = postgres
quarkus.datasource.password = postgres
#Authorisierung
quarkus.http.auth.basic=true
quarkus.security.jdbc.realm-name=quarkus
quarkus.security.jdbc.enabled=true
quarkus.security.jdbc.principal-query.sql=SELECT n.hash, n.salt, n.iterations FROM nutzer n WHERE n.nutzername=?
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=2
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.iteration-count-index=3
quarkus.security.jdbc.principal-query.bcrypt-password-mapper.hash-encoding=BASE64
quarkus.security.jdbc.principal-query.roles.sql=SELECT nb.berechtigungen_name FROM nutzer n JOIN nutzer_berechtigung nb ON nb.nutzers_nutzername = n.nutzername WHERE n.nutzername=?
quarkus.security.jdbc.principal-query.roles.datasource=permissions
quarkus.security.jdbc.principal-query.roles.attribute-mappings.0.index=1
quarkus.security.jdbc.principal-query.roles.attribute-mappings.0.to=groups
# drop and create the database at startup (use `update` to only update the schema)
quarkus.hibernate-orm.database.generation=drop-and-create
#Always include swagger-ui
quarkus.swagger-ui.always-include=true
我们没有收到错误消息,只是无法对用户进行身份验证。
我们是否在配置中犯了错误,或者我们是否使用了错误的算法或 bCrypt 版本?
最佳答案
您可以使用 wildfly github 中的示例生成有效的哈希值和盐:
static final Provider ELYTRON_PROVIDER = new WildFlyElytronPasswordProvider();
static final String TEST_PASSWORD = "myPassword";
public static void main(String[] args) throws Exception {
PasswordFactory passwordFactory = PasswordFactory.getInstance(BCryptPassword.ALGORITHM_BCRYPT, ELYTRON_PROVIDER);
int iterationCount = 10;
byte[] salt = new byte[BCryptPassword.BCRYPT_SALT_SIZE];
SecureRandom random = new SecureRandom();
random.nextBytes(salt);
IteratedSaltedPasswordAlgorithmSpec iteratedAlgorithmSpec = new IteratedSaltedPasswordAlgorithmSpec(iterationCount, salt);
EncryptablePasswordSpec encryptableSpec = new EncryptablePasswordSpec(TEST_PASSWORD.toCharArray(), iteratedAlgorithmSpec);
BCryptPassword original = (BCryptPassword) passwordFactory.generatePassword(encryptableSpec);
byte[] hash = original.getHash();
Encoder encoder = Base64.getEncoder();
System.out.println("Encoded Salt = " + encoder.encodeToString(salt));
System.out.println("Encoded Hash = " + encoder.encodeToString(hash));
}
请注意,WildFlyElytronProvider() 到目前为止已被弃用,因此您必须改用 WildFlyElytronPasswordProvider()。
关于java - Quarkus 使用哪个版本的 bcrypt 以及如何生成有效的哈希值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59683420/