WildFly:Java EE应用程序中的随机添加密码 [英] WildFly: randomly salted passwords in Java EE application

查看:58
本文介绍了WildFly:Java EE应用程序中的随机添加密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用WildFly(8.2)处理存储在数据库中的随机加盐密码的方法是什么?

What is the WildFly (8.2) way to work with randomly salted passwords stored in a database?

org.jboss.crypto.digest.DigestCallback的实现(在密码验证过程中)是否意味着可以从数据库访问盐部分?

Is an implementation of org.jboss.crypto.digest.DigestCallback (in the password validation process) meant to have access to the salt part from the database?

还是我应该简单地自己对密码进行哈希处理和加盐处理,然后再将其交给HttpServletRequestlogin方法?

Or should I simply hash and salt passwords by my self before handing them over to the login method of HttpServletRequest?

推荐答案

在我看来,处理密码的"WildFly方法"是执行大多数容器的操作并提供非安全的解决方案-盒子.我不知道为什么,但是到目前为止,我所见过的每个标准JDBC领域实现都只是在不加盐的情况下对密码进行哈希处理……这是完全不安全的.

It looks to me like the 'WildFly way' to deal with passwords is to do what most containers do and deliver a non-secure solution out-of-the-box. I don't know why, but every standard JDBC realm implementation I've seen so far just hashes the passwords without salt... Which is totally insecure.

开源解决方案

我发现了一个适用于WildFly的即用型解决方案.我最终自己使用了它,并且效果很好.我可以推荐:

I found an out-of-the box solution that works on WildFly. I ended up using it myself and it works well. I can recommend it:

m9aertner/PBKDF2

这是我的配置方式:

首先通过在modules/下创建一个文件夹向WildFly添加模块,如下所示:

First add a module to WildFly by creating a folder below modules/, like this:

C:\WildFly\v8.2.0\modules\de\rtner\PBKDF2\main

PBKDF2-1.1.0.jar文件以及具有以下内容的module.xml放入其中:

Place the PBKDF2-1.1.0.jar file in it along with a module.xml with these contents:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="de.rtner.PBKDF2">
  <resources>
    <resource-root path="PBKDF2-1.1.0.jar"/>
  </resources>
  <dependencies>
    <module name="org.picketbox"/>
    <module name="javax.api"/>
  </dependencies>
</module>`

然后,将领域配置添加到standalone.xml:

Then, add a realm configuration to standalone.xml:

<subsystem xmlns="urn:jboss:domain:security:1.2">
  <security-domains>
    <!-- .... -->

    <security-domain name="MyRealm">
      <authentication>
        <login-module code="de.rtner.security.auth.spi.SaltedDatabaseServerLoginModule" flag="required" module="de.rtner.PBKDF2">
          <module-option name="dsJndiName" value="java:/jdbc/MyDS"/>
          <module-option name="principalsQuery" value="SELECT password FROM users WHERE username = ?"/>
          <module-option name="rolesQuery" value="SELECT roles.name AS groupid, 'Roles' FROM roles INNER JOIN user_roles ON roles.name = users.username WHERE users.username = ?"/>
          <module-option name="unauthenticatedIdentity" value="guest"/>
          <!-- DEFAULT HASHING OPTIONS:
          <module-option name="hmacAlgorithm" value="HMacSHA1" />
          <module-option name="hashCharset" value="UTF-8" />
          <module-option name="formatter" value="de.rtner.security.auth.spi.PBKDF2HexFormatter" />
          <module-option name="engine" value="de.rtner.security.auth.spi.PBKDF2Engine" />
          <module-option name="engine-parameters" value="de.rtner.security.auth.spi.PBKDF2Parameters" />
          -->
        </login-module>
      </authentication>
    </security-domain>

    <!-- .... -->
  </security-domains>
</subsystem>

SQL查询与标准DatabaseLoginModule相同.无需指定默认的哈希选项(因为它们是默认值),但是在创建新用户时,您确实需要意识到它们(并正确设置它们),以便使用相同的参数正确地哈希其密码.

The SQL queries are the same as for the standard DatabaseLoginModule. The default hashing options need not be specified (as they are default) but you do need to be aware of them (and set them correctly) when creating new users in order to hash their password correctly with the same parameters.

示例用法

这是我在代码中所做的工作,用于基于给定的纯文本创建新的密码哈希(包括盐):

Here is what I am doing in my code to create a new password hash (including salt) based on a given plaintext:

public static String hash(String plainText, String storedPassword) {
    if (plainText == null) return null;
    SimplePBKDF2 crypto = new SimplePBKDF2();
    PBKDF2Parameters params = crypto.getParameters();
    params.setHashCharset("UTF-8");
    params.setHashAlgorithm("HmacSHA1");
    params.setIterationCount(1000);
    if (storedPassword != null) {
        new PBKDF2HexFormatter().fromString(params, storedPassword);
    }
    return crypto.deriveKeyFormatted(plainText);
}

创建新密码时,您将通过传递null作为storedPassword来调用此函数:

When creating a new password, you would call this function passing null as the storedPassword:

String password = hash('MySecretPassword', null);

password最终看起来像这样:

"192EAEB3B7AA40B1:1000:4C137AF7AD0F3999D18E2B9E6FB726D5C07DE7D5"

比较密码时,您调用相同的函数,并传递原始密码,然后比较结果:

When comparing passwords, you call the same function, passing the original password and then compare the results:

String enteredPassword = hash(userInput, password);
if (enteredPassword.equals(password)) {
    // Ok!
}

您需要传递原始密码的原因是,哈希参数和盐存储在密码哈希中,因此算法需要存储的密码来获取这些参数并将其用于新哈希.但是,您通常不需要自己比较密码,因为登录模块中已经完成了此操作.

The reason you need to pass the original password is that the hashing parameters and salt are stored in the password hash, so the algorithm needs the stored password to get these parameters and use them for the new hash. However you don't usually need to compare passwords yourself as this is already done in the login module.

或者,自己滚动

此博客文章提供了一些解释有关如何推出自己的Realm实现的示例,该实现确实会加盐.他在GitHub上有源代码那.

This blog post gives some explanation on how to roll your own Realm implementation that does add salt. He has source code on GitHub so maybe use that.

这是针对Glassfish的,但我认为就Realm实现代码而言,这无关紧要.

It's for Glassfish, but I think it doesn't matter as far as the Realm implementation code goes.

这篇关于WildFly:Java EE应用程序中的随机添加密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆