【问题标题】:How do I calculate a SHA-256 Tomcat 8 DataSourceRealm compatible hash in Java code?如何在 Java 代码中计算 SHA-256 Tomcat 8 DataSourceRealm 兼容哈希?
【发布时间】:2015-03-15 16:14:32
【问题描述】:

我正在使用 Tomcat 8.0.17 和 JDK 1.8.0_25。我正在使用 Derby 作为数据库。

我有一个使用 SHA-256 摘要的 FORM 身份验证的 DataSourceRealm。

我的 $WEBAPP/META-INF/context.xml 看起来像这样:

<Context> 
  <ResourceLink global="jdbc/demo" name="jdbc/demo" type="javax.sql.DataSource" />
  <Realm className="org.apache.catalina.realm.DataSourceRealm"
         digest="SHA-256"
         dataSourceName="jdbc/demo"
         userTable="users" userNameCol="user_name" userCredCol="user_pass"
         userRoleTable="user_roles" roleNameCol="role_name"/>
</Context> 

使用 Tomcat 附带的摘要工具时,我可以使用摘要工具的输出手动更新数据库中的 users.user_pass 列,并且一切正常(注意 -s 0,因为 Tomcat 不适用于加盐哈希):

C:\>"%CATALINA_HOME%\bin\digest" -a SHA-256 -s 0 hotdog
hotdog:$1$35602208e86ac7d6b3a63780a9538a9d1763a646d5b9f3930a0548e0983e0ca6

...

ij> update users set user_pass='$1$35602208e86ac7d6b3a63780a9538a9d1763a646d5b9f3930a0548e0983e0ca6' where user_name='demouser';
1 row inserted/updated/deleted

现在我可以成功登录了。

现在我如何以编程方式(在 Java 中)生成 SHA-256 散列密码以插入数据库?我见过很多生成 SHA-256 哈希并将字节字符串转换为十六进制的示例。但是让我失望的部分是使用摘要工具时哈希的开头。它总是在开头生成带有“$”的哈希。当以编程方式转换哈希并以十六进制编码时,输出中永远不会包含“$”字符(因为十六进制中没有“$”,只有 0-F)。但 Tomcat 似乎与摘要工具输出(包括美元符号)配合得很好。

【问题讨论】:

    标签: tomcat datasource sha256 jdbcrealm


    【解决方案1】:

    消化器的结果以以下格式输出:

    密码:salt$iterations$digest

    例如,密码“1234”、20 个字符的盐和 10 次迭代将产生:

    1234:d83beb29c66cd2f021a469875ffd4c608c25d855$10$eab99fbeedfd7d01b94cd3cf8484a99ad671726faa3e5d48c0699b489aa35658

    【讨论】:

      【解决方案2】:

      我刚刚对其进行了测试,我猜 Tomcat 只是从摘要工具输出中剥离了直到第二个美元符号的所有内容。所以我可以使用 Apache Commons 在 Java 中生成一个 SHA-256 哈希十六进制字符串:

      String sha256hex = org.apache.commons.codec.digest.DigestUtils.sha256Hex(password);  
      

      编辑:那么摘要工具生成的哈希字符串中的“$”符号的意义是什么?我猜是和盐有关?

      【讨论】:

        【解决方案3】:


        打包测试应用程序; import java.security.NoSuchAlgorithmException; import javax.xml.bind.DatatypeConverter; /** * * @author Martin */ public class TestApp { /** * @param args the command line arguments */ public static void main(String[] args) { /* testing how to salted sha-256 like tomcat digest.sh -> credential:salt$iterations$hash /usr/local/apache-tomcat-8.0.26/bin/digest.sh -a SHA-256 NonGuesablePassword NonGuesablePassword:a2eda424107c276748780bca8e7d46256321345e1fd0d0d0bcdbcee72dcc0a4a$1$8f2027b86b0b475be7d09c737995037864a4dbc44d90f24648680169b246a9c7 */ String pwd="NonGuesablePassword"; String salt="a2eda424107c276748780bca8e7d46256321345e1fd0d0d0bcdbcee72dcc0a4a"; String hash="8f2027b86b0b475be7d09c737995037864a4dbc44d90f24648680169b246a9c7"; try { System.out.println(hash+" 1st iteration hash"); java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-256"); md.update(DatatypeConverter.parseHexBinary(salt)); md.update(pwd.getBytes()); System.out.println(DatatypeConverter.printHexBinary(md.digest())+ " 1st iteration") ; // encrypte sha-256 versie System.out.println(DatatypeConverter.printHexBinary(md.digest())+ " 2nd iteration") ; // encrypte sha-256 versie } catch (NoSuchAlgorithmException na) { System.out.println(na.getMessage()); } } }

        也:tomcat 在使用摘要时识别 userCredCol 字段中的 2 个 $ 符号。没有 $ 它使用未加盐的版本,这等于 0 的盐大小和 1 次迭代,例如 "$1$hash" 或 "hash" 是相同的。

        另外:并非所有的 tomcat 都有相同的摘要版本。 pe 与 8.0.26 不同,8.0.14 不具备使用盐的 sha-256 的可能性。将加盐信息放入 userCredCol 显然是行不通的。

        【讨论】:

          猜你喜欢
          • 2014-08-19
          • 2023-03-27
          • 1970-01-01
          • 2010-12-17
          • 2012-06-15
          • 2011-11-02
          • 1970-01-01
          • 2019-07-21
          • 1970-01-01
          相关资源
          最近更新 更多