coldfusion - SHA-512 对 ColdFusion 中的字节数组进行哈希处理

标签 coldfusion bytearray sha512

我正在使用 ColdFusion 9

引用 Ben Nadel 关于 his blog 的优秀作品,我试过了

ucase(digestUtils.sha512(imageBinary))

对于 SHA-512 哈希,我感到害怕:

The sha512 method was not found. Either there are no methods with the specified method name and argument types or the sha512 method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity.

现在我知道 sha512 确实作为一种方法存在,因为我看到了它 here ,但是当我执行

cfdump var="#digestUtils#"

我只得到:

md5(byte[])     byte[]
md5(java.lang.String)   byte[]
md5Hex(byte[])  java.lang.String
md5Hex(java.lang.String)    java.lang.String
sha(java.lang.String)   byte[]
sha(byte[])     byte[]
shaHex(java.lang.String)    java.lang.String
shaHex(byte[])  java.lang.String

其他方法怎么了?我想我必须尝试别的东西。

请告知 ColdFusion 解决方案。 ColdFusion/Java 解决方案也可以。 我正在尝试编写一个 SSO 应用程序,第 3 方人员向我提供 URL 参数。我已成功解码第一个参数以获取我的 XML 帖子。我现在需要获取第二个参数,即哈希有效负载,并通过算法确保我的第一个参数未被篡改。

========= 编辑从这里开始:好吧,我又试了一遍代码,还是不行。

算法听起来很简单。但是尝试实现它让我很痛苦。

1. compute the hash string value of the XMLPost string above:
 a. convert the base64 salt string to a UTF-8 byte array.
 b. convert the base64 XML payload string to a UTF-8 byte array.
 c. create a new byte array consisting of the XML payload bytes from step b, appended with the salt bytes from step a.
 d. perform a SHA512 hash on the concatenated byte array from step c, which results in a hashed byte array.
 e. create a new byte array consisting of the hashed bytes from step d, appended with the salt bytes from step a.
 f. convert the result of step e to a base64-encoded string and should be the value of query string parameter "h" payload hash.

xmlPost 是由我的第三方人员创建的: 此 XML 负载字符串被转换为 UTF-8 字节数组,然后又被转换为 base-64 字符串。生成的 base-64 字符串是我下面的 xmlPost 的值。

所以我这样做:

<code>
<cfset xmlPost = urlDecode("PD94bWwgdmVyc2lvbj0iMS4wIj8%2bPEVzdG9yZVNzb0N1c3RvbWVyIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPjxDdXN0b21lcklkPjExMjk0MDwvQ3VzdG9tZXJJZD48RGVhbGVyQ29kZT5OODg4ODg8L0RlYWxlckNvZGU%2bPFBvaW50QmFsYW5jZT4yODA8L1BvaW50QmFsYW5jZT48Rmlyc3ROYW1lPkZhaXRoPC9GaXJzdE5hbWU%2bPExhc3ROYW1lPkh1dHVsYTwvTGFzdE5hbWU%2bPC9Fc3RvcmVTc29DdXN0b21lcj4%3d") />
<cfset salt = "3dfjh674!MujErf98344@090" />
<cfset payload_hash = urlDecode("EtLDRJfcRESFKpY4OGZZnRSN2THqT%2bEelzOuXVU06jotd2kE4yKnlYay7BqyAdcUSATRgSMaHxZa6uBqKKd9rjNkZmpoNjc0IU11akVyZjk4MzQ0QDA5MA%3d%3d") />

<cfset strXML = ToString( ToBinary( xmlpost ) ) /> <!--- to get actual XML --->

<!--- base64 encoding returns a byte array --->
<cfset saltByteArray = toBase64( salt, "utf-8" )  /> 
<cfset xmlpostByteArray = toBase64( xmlPost, "utf-8" ) />
<!--- append salt to xmlpost --->
<cfset xmlpostsaltByteArray = xmlpostByteArray & saltByteArray />

<!--- now let us perform a sha512 hash on this concatenated byte array --->
<cfscript>
// Create an instance of our DigestUtils class
digestUtils = createObject("java","org.apache.commons.codec.digest.DigestUtils");
// I hash a byte array using the given algorithm and return a
// 32-character Hexadecimal string. Home-made hash function for CF9 and earlier
function hashBytes( bytes, algorithm = "SHA-512" ){
    // Get our instance of the digest algorithm that we'll use
    // to hash the byte array.
    var messageDigest = createObject( "java", "java.security.MessageDigest" ).getInstance( javaCast( "string", algorithm ) );

    // Get the digest for the given byte array. This returns the
    // digest (i.e., hash) in byte-array format.
    var digest = messageDigest.digest( bytes );

    // Now that we have our digested byte array (i.e., our hash as another byte
    // array), we have to convert that into a HEX string. So, we'll need a HEX buffer.
    var hexBuffer = [];

    // Each integer in the byte digest needs to be converted into
    // a HEX character (with possible leading zero).
    for (byte =1 ;byte LTE ArrayLen(digest);byte = byte + 1) {
    //for ( var byte in digest){
        // Get the hex value for this byte. When converting the
        // byte, only use the right-most 8 bits (last 8 bits of the integer)
        // otherwise the sign of the byte can create oddities

        var tail = bitAnd( 255, byte );

        // Get the hex-encoding of the byte.
        var hex = ucase( formatBaseN( tail, 16 ) );

        // In order to make sure that all of the HEX characters
        // are two-digits, we have to prepend a zero for any
        // value that was originally LTE to 16 (the largest value
        // that won't result in two HEX characters).
        arrayAppend( hexBuffer, (tail <= 16 ? ("0" & hex) : hex) );
    }

    // Return the flattened character buffer.
    return( arrayToList( hexBuffer, "" ) );
}

// Get the hash of the byte array using our hashBytes() function
hashByteArray = hashBytes( xmlpostsaltByteArray );  
</cfscript>


<!--- The hashByteArray is in HEX format now. Convert to binary --->
<!--- You must binary decode the hashed string before converting it to binary --->
<cfset hashByteArray = toBase64( BinaryDecode( hashByteArray, 'HEX' ) ) />

<!--- The final step is to append this new hashbytearray with the salt byte array --->

<cfset hashByteArray = hashByteArray & saltByteArray />

<!--- now convert this value to a base64 encoded string --->

<cfset hashByteArray2 = toBase64( hashByteArray )/>

这里是我得到的 strXML 变量:

Actual xml structure converted from base 64 to string:
<?xml version="1.0"?><EstoreSsoCustomer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><CustomerId>112940</CustomerId><DealerCode>N88888</DealerCode><PointBalance>280</PointBalance><FirstName>Faith</FirstName><LastName>Hutula</LastName></EstoreSsoCustomer>  

最终值 hasByteArray2 与 payload_hash 一点也不相似

这是我第一次这样做,几十年前我对哈希、字节数组和字符转换的理解就飞出窗外了。

我做错了什么?

谢谢 信仰斯隆

最佳答案

DigestUtils.sha512在 1.4 版本中添加。 ColdFusion 9 使用旧版本 1.3。这就是找不到该方法的原因。

使用基于MessageDigest 的其他功能。请确保传递正确的算法即:

    imageHash = hashBytes( imageBinary, "SHA-512" );

更新:根据更新后的代码,一些说明可能有点误导。我相信他们只是将 xmlsalt 字符串从给定的编码(base64 和 utf-8)解码为 字节数组,而不是字符串:

    // note: salt value has invalid characters for base64
    // assuming it is a plain utf-8 string
    saltArray = charsetDecode(salt, "utf-8");
    xmlByteArray = binaryDecode(xmlPost, "base64");

然后合并两个二进制数组(见自定义函数)

    mergedBytes = mergeArrays( xmlByteArray, saltArray );

计算新字节数组的哈希值:

    messageDigest = createObject( "java", "java.security.MessageDigest" );
    messageDigest = messageDigest.getInstance( javaCast( "string", "SHA-512") );
    hashedByteArray = messageDigest.digest( javacast("byte[]", mergedBytes) );

再次合并数组:

    mergedBytes = mergeArrays( hashedByteArray, saltArray);

最后将二进制转成base64并比较:

    calculatedPayload = binaryEncode( javacast("byte[]", mergedBytes), "base64");

    // check results
    arePayloadsEqual = compare(calculatedPayload, payload_hash) eq 0;
    WriteDump("arePayloadsEqual="& arePayloadsEqual);
    WriteDump("calculatedPayload="& calculatedPayload);
    WriteDump("payload_hash="& payload_hash);

注意:BinaryDecode/CharsetDecode 返回 java 数组。与 CF 数组不同,它们是不可变的(即无法更改)。所以 handy addAll(..) trick不会在这里工作。

    // merge immutable arrays the long way
    function mergeArrays( array1, array2 ){
        var i = 0;
        var newArray = [];
        for (i = 1; i <= arrayLen(arguments.array1); i++) {
            arrayAppend(newArray, arguments.array1[i]);
        }
        for (i = 1; i <= arrayLen(arguments.array2); i++) {
            arrayAppend(newArray, arguments.array2[i]);
        }
        return newArray;
    }   

关于coldfusion - SHA-512 对 ColdFusion 中的字节数组进行哈希处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29839790/

相关文章:

hash - 散列密码的最佳实践 - SHA256 还是 SHA512?

php - 哈希函数在ColdFusion 10+和PHP 7.x上的功能相同吗?

c# - crypt SHA-512 算法的说明 (c#)

jquery - IE 中非常奇怪的 url,页面 404 错误

mysql - Coldfusion Lucee 4.5.2.018 (Linux) - REST 服务(无法转换字符串)JSON

oop - 使用重复的 CFC 名称是否安全/可以接受?

MySQL 服务器 : How to install without "Workbench"?

java - Java 中的 LSB/MSB 处理

java - 如何在 Java 中将一个或多个字符串转换为字节数组中的不同范围?

flash - AS3在循环中使用Sound.extract分析声音文件