SHA-512 在 ColdFusion 中散列一个字节数组 [英] SHA-512 hashing a byte array in ColdFusion

查看:20
本文介绍了SHA-512 在 ColdFusion 中散列一个字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ColdFusion 9

I am using ColdFusion 9

他的博客,我试过了

ucase(digestUtils.sha512(imageBinary))

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

For SHA-512 hashing I get that dreaded:

找不到 sha512 方法.要么没有方法指定的方法名称和参数类型或 sha512 方法是重载了 ColdFusion 无法破译的参数类型可靠.ColdFusion 找到 0 个与提供的匹配的方法论据.如果这是一个 Java 对象并且您验证了该方法存在,使用javacast函数减少歧义.

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 确实作为一种方法存在,因为我看到了它 这里,但是当我执行一个

Now I know that sha512 does indeed exist as a method, because I saw it here, but when I perform a

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

其他方法发生了什么?我想我得试试别的了.

What happened to the other methods? I guess I have to try something else.

请提供 ColdFusion 解决方案.ColdFusion/Java 解决方案也可以.我正在尝试编写一个 SSO 应用程序,其中第 3 方人员向我提供 URL 参数.我已成功解码第一个参数以获取我的 XML Post.我现在需要获取作为哈希负载的第二个参数并通过算法来确保我的第一个参数没有被篡改.

Please advise with a ColdFusion solution. A ColdFusion/Java solution would be ok too. I'm trying to write a SSO application where the 3rd party guys feeds me URL parameters. I have successfully decoded the 1st parameter to get my XML Post. I now need to take the 2nd parameter which is the hash payload and go through the algorithm to ensure my 1st parameter hasn't been tampered with.

=========编辑从这里开始:好的,我尝试再次编写代码无济于事.

========= Editing begins here: Okay,I tried writing the code again to no avail.

算法听起来很简单.但是试图实现它让我很生气.

The algorithm sounds simple enough. But trying to implement it is killing me.

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 的值.

xmlPost was created by my third party guys as such: This XML payload string was converted to a UTF-8 byte array, which was then converted to a base-64 string. The resulting base-64 string is the value of my xmlPost below.

所以我这样做:

<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 变量得到的结果:

Here is what I get for my strXML variable:

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 远不相似

The final value, hasByteArray2 is not even remotely similar to payload_hash

这是我第一次这样做,几十年前我对散列、字节数组和字符转换的理解就一飞冲天了.

This is my first time doing this and my understanding of hashing, byte arrays and character conversions flew out of the window decades ago.

我做错了什么?

谢谢信仰斯隆

推荐答案

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

DigestUtils.sha512 was added in version 1.4. ColdFusion 9 uses an older version, 1.3. That is why the method is not found.

使用基于MessageDigest的其他函数.请务必传入正确的算法,即:

Use the other function based on MessageDigest. Just be sure to pass in the correct algorithm ie:

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

<小时>

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


UPDATE: Based on the updated code, some of the instructions may be a bit misleading. I believe they just mean decode the xml and salt strings from their given encoding (base64 and utf-8) into byte arrays, not strings:

    // 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");

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

Then merge the two binary arrays (see custom function)

    mergedBytes = mergeArrays( xmlByteArray, saltArray );

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

Calculate the hash of the new byte array:

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

再次合并数组:

    mergedBytes = mergeArrays( hashedByteArray, saltArray);

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

Finally convert the binary to base64 and compare:

    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 数组不同,它们是不可变的(即不能更改).所以 方便的 addAll(..) 技巧 在这里不起作用.

Note: BinaryDecode/CharsetDecode return java arrays. Unlike CF arrays, they are immutable (ie cannot be changed). So the handy addAll(..) trick will not work here.

    // 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;
    }   

这篇关于SHA-512 在 ColdFusion 中散列一个字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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