Вопрос по – SHA-512 хэширует массив байтов в ColdFusion

1

Я использую ColdFusion 9

Ссылка на хорошие работы Бена Наделяего блог, Я старался

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 действительно существует как метод, потому что я видел егоВот, но когда я выполняю

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 тоже подойдет. Я пытаюсь написать приложение для единого входа, где сторонние парни передают мне параметры URL. Я успешно расшифровал 1-й параметр, чтобы получить свой XML Post. Теперь мне нужно взять 2-й параметр, который является полезной нагрузкой хэша, и пройти алгоритм, чтобы убедиться, что мой 1-й параметр не был подделан.

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

Алгоритм звучит достаточно просто. Но попытка осуществить это убивает меня.

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 = "[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

Я делаю это впервые, и мое понимание хэширования, массивов байтов и преобразования символов вылетело из окна десятилетия назад.

Что я делаю неправильно?

Спасибо Faith Sloan

Ваш Ответ

1   ответ
3

DigestUtils.sha512 был добавлен в версии 1.4. ColdFusion 9 использует более старую версию 1.3. Именно поэтому метод не найден.

Используйте другую функцию, основанную наMessageDigest, Просто убедитесь, что передали правильный алгоритм, т.е.

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

UPDATE: На основании обновленного кода некоторые инструкции могут вводить в заблуждение. Я считаю, что они просто означают расшифроватьxml а такжеsalt строки из заданной кодировки (base64 и utf-8) вbyte arrays, а не строки:

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

Note: BinaryDecode/CharsetDecode вернуть массивы Java. В отличие от массивов CF, они неизменны (то есть не могут быть изменены). Итакудобный трюк addAll (..) не будет работать здесь.

    // 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;
    }   
Error: User Rate Limit Exceeded Faith Sloan
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Faith Sloan
Error: User Rate Limit Exceeded Faith Sloan
Error: User Rate Limit Exceeded

Похожие вопросы