【问题标题】:How to Generate Matching MD5 Hash: SQL Server nvarchar Field vs. ColdFusion如何生成匹配的 MD5 哈希:SQL Server nvarchar 字段与 ColdFusion
【发布时间】:2011-04-10 15:02:11
【问题描述】:

我试图弄清楚如何在 SQL Server 和 ColdFusion 之间生成匹配的 MD 5 哈希值。根本原因似乎是 SQL Server 字段是 nvarchar 数据类型,这似乎意味着我需要对我将在 ColdFusion 或 Java 中散列的字符串进行编码以使其匹配,但我无法想办法。要清楚这是否是 SQL Server varchar 字段,一切正常。

这是我正在尝试的代码:

<cfset stringToHash = "Hello world!">

<cfquery name="sqlserver" datasource="#mySqlServerDSN#">
    SELECT RIGHT( 
    master.dbo.fn_varbintohexstr( 
        HashBytes( 
            'MD5', 
            CAST(<cfqueryparam value="#stringToHash#" cfsqltype="cf_sql_varchar">  AS nvarchar(max))      
        ) 
    ) 
   , 32) AS HASHED
</cfquery>

<cfoutput>
<pre>
CF UFT-8:   #hash(stringToHash, 'MD5', 'UTF-8')#
CF UFT-16:  #hash(stringToHash, 'MD5', 'UTF-16')#
SQL Server: #sqlserver.hashed#
</pre>
</cfoutput>

生产

CF UTF-8:   86FB269D190D2C85F6E0468CECA42A20
CF UTF-16:  0C89A9720D83539E3723BB99C07D069F
SQL Server: f9a6119c6ec37ce652960382f8b59f2c

所以我猜我需要将传递给hash() 的最后一个参数更改为不同的编码,但我无法弄清楚。我也将此问题标记为 Java,因为我也很乐意用该语言回答。

【问题讨论】:

  • 看起来其他人在使用 .Net stackoverflow.com/questions/5341556/… 时遇到了这个问题,我没有办法测试它,但也许 CF UTF-16 编码默认是 Big Endian?
  • 如果要将纯字符串值与 SQL hased 列进行比较,请将纯字符串传递给 SQL 并使用 SQL 散列。然后与该列进行比较。在 CF 代码中检查是否有任何具体要求?

标签: java sql-server coldfusion


【解决方案1】:

默认情况下,SQL Server 对 nvarchar 字段使用 UTF-16 in little-endian 字节顺序字符集。 在 ColdFusion 中,您必须使用“UTF-16LE”字符集。

<cfscript>
    helloWorld = "Hello, World!";
    utf8HashCF = lcase(hash(helloWorld, 'MD5', 'UTF-16LE'));
</cfscript>
<cfoutput>
    #utf8HashCF# <br />
</cfoutput>

【讨论】:

  • 这是正确的。以为我已经用哈希函数尝试过这种编码,但显然不是。很想看到一些关于 nvarchar 字节序的文档。
  • 奇怪的是,当我尝试使用 @StefanoDiFabio java 版本使用 UTF-16LE 时,它不起作用。 ColdFusion 正在做一个或两个额外的步骤来让它工作。
【解决方案2】:

我很好奇为什么你的 sql server 列是 nvarchar;哈希不是必需的。 nvarchar 用于存储扩展字符集,您不应该从散列函数中获取这些字符集。

不管怎样,我尝试了 CF9 中可用的所有哈希算法,但都没有生成您要查找的哈希。

除非您出于某种尚未解释的原因需要将该列设置为 nvarchar,否则为什么不将其更改为 varchar?

【讨论】:

  • 正如 Adam 所发布的 - 我检查了 SQL Server 2008,但将查询更改为 CAST('Hello world!' AS varchar(32)) 并获得了您的 CF UTF-8 哈希。
【解决方案3】:

我不认为这是 CF 散列,因为如果您将 CF 与 Java 进行比较,它们会创建相同的散列。我的盒子上的 CF 和 Java 都输出“65a8e27d8879283831b664bd8b7f0ad4”,当我将强制转换更改为 varchar(32) 时,它与 SQL 哈希匹配。

过去,当我需要进行任何类型的哈希创建和比较时,我创建了一个返回字符串的服务,因此您不必担心跨平台算法问题。您也可以让 sql 为您完成所有工作,但是您将业务逻辑放在错误的层中,但每个层都有自己的。

<cfscript>
    helloWorld = "Hello, World!";

    javaString = CreateObject( "java", "java.lang.String" ).Init(helloWorld);
    javaHash = CreateObject( "java", "java.security.MessageDigest" ).getInstance("MD5");

    javaHash.reset();
    javaHash.update(javaString.getBytes("UTF-8"),0,javaString.length());

    javaBigInt = CreateObject( "java", "java.math.BigInteger" ).Init(1,javaHash.digest());

    utf8HashCF = lcase(hash(helloWorld, 'MD5', 'UTF-8'));
    utf8HashJava = variables.javaBigInt.toString(16);
</cfscript>
<cfoutput>
    #utf8HashCF# <br />
    #utf8HashJava#
</cfoutput>

【讨论】:

    猜你喜欢
    • 2016-06-24
    • 2012-07-22
    • 2014-05-19
    • 1970-01-01
    • 2020-12-08
    • 2013-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多