2012-05-25 69 views
1
字節數組

我使用ColdFusion 9SHA-512散列中的ColdFusion

引用本·納德爾的好作品上his blog,我試圖

ucase(digestUtils.sha512(imageBinary)) 

對於SHA-512散列我得到那個可怕的:

未找到sha512方法。要麼沒有指定方法名稱和參數類型的方法,要麼sha512方法是 ,它們重載了參數類型,ColdFusion無法可靠地解密 。 ColdFusion找到了0個與提供的 參數匹配的方法。如果這是一個Java對象,並且您確認存在方法 ,請使用javacast函數來減少歧義。

現在我知道,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應用程序,其中第三方人員向我提供URL參數。我已經成功解碼第一個參數來獲得我的XML Post。我現在需要獲取散列負載的第二個參數並通過算法來確保我的第一個參數沒有被篡改。

========= 編輯從這裏開始:好吧,我試着再次寫代碼無濟於事。

該算法聽起來很簡單。但試圖實現它正在殺死我。

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字節數組,然後將其轉換成基-64字符串。生成的base-64字符串是下面的my xmlPost的值。

所以我這樣做:

<code> 
<cfset xmlPost = urlDecode("PD94bWwgdmVyc2lvbj0iMS4wIj8%2bPEVzdG9yZVNzb0N1c3RvbWVyIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPjxDdXN0b21lcklkPjExMjk0MDwvQ3VzdG9tZXJJZD48RGVhbGVyQ29kZT5OODg4ODg8L0RlYWxlckNvZGU%2bPFBvaW50QmFsYW5jZT4yODA8L1BvaW50QmFsYW5jZT48Rmlyc3ROYW1lPkZhaXRoPC9GaXJzdE5hbWU%2bPExhc3ROYW1lPkh1dHVsYTwvTGFzdE5hbWU%2bPC9Fc3RvcmVTc29DdXN0b21lcj4%3d") /> 
<cfset salt = "[email protected]" /> 
<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

這是我第一次做這個和我對哈希的理解,字節a數十年前的蟲子和角色轉換飛離了窗口。

我在做什麼錯?

謝謝 信仰斯隆

回答

3

DigestUtils.sha512在1.4版本中加入。 ColdFusion 9使用較舊的版本1.3。這就是沒有找到該方法的原因。

使用基於MessageDigest的其他功能。只要確保在正確的算法,即通過:

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

UPDATE:基於更新的代碼,一些指令可能會有點誤導。我相信他們只是說從他們給出的編碼(Base64和UTF-8)的xmlsalt字符串解碼成字節數組,而不是字符串:

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

我試過並嘗試過,並試圖無法獲得匹配的哈希值。見上面編輯過的帖子。 –

+0

我還沒有看到任何編輯。當您發佈樣本值時,請告知我。 – Leigh

+0

樣本值在代碼中。 xmlpost,salt和payload_hash。我的計算哈希應該與payload_hash相同。但事實並非如此。我還向您展示了我解碼的strXML,它對於xmlpost是正確的。我的問題是哈希。 –