Невозможно создать действительную подпись для API, используя ColdFusion и HMAC-SHA1
Я просмотрел ряд других связанных сообщений на эту тему и смог воспроизвести их без проблем. Однако я не могу получить ожидаемый результат подписи, используя мои собственные данные, независимо от того, что я пытаюсь сделать. Я был бы очень признателен за любую помощь. Вот требования API:
- Преобразовать данные для подписи из строки ASCII в байтовый массив
- Преобразуйте ваш секретный ключ доступа из строки Base64 в байтовый массив
- Используйте байтовый массив, созданный на шаге 1, в качестве ключа для подписавшего HMAC-SHA1
- Рассчитать HMAC-SHA1 хеш байтового массива, созданного на шаге 2. Результатом будет байтовый массив
- Преобразовать байтовый массив, созданный на шаге 3, в строку в кодировке Base64
Согласно документации:
- Предполагая, что ваш секретный ключ доступа имеет вид "АААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААААА ="
- Предполагается, что данные для подписи " http://membersuite.com/contracts/IConciergeAPIService/WhoAmI00000000-0000-0000-0000-00000000000011111111-1111-1111-1111-111111111111"
- Подпись должна быть "2zsMYdHb/MJUeTjv5cQl5pBuIqU="
Мне не удалось получить эту подпись, несмотря на то, что я пробовал различные методы из других постов. Например:
<cffunction name="hmacEncrypt" returntype="binary" access="public" output="false">
<cfargument name="base64Key" type="string" required="true" default="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==">
<cfargument name="signMessage" type="string" required="true" default="http://membersuite.com/contracts/IConciergeAPIService/WhoAmI00000000-0000-0000-0000-00000000000011111111-1111-1111-1111-111111111111">
<cfargument name="encoding" type="string" default="UTF-8">
<cfset var messageBytes = JavaCast("string",arguments.signMessage).getBytes(arguments.encoding)>
<cfset var keyBytes = binaryDecode(arguments.base64Key, "base64")>
<cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec")>
<cfset var mac = createObject("java","javax.crypto.Mac")>
<cfset key = key.init(keyBytes,"HmacSHA512")>
<cfset mac = mac.getInstance(key.getAlgorithm())>
<cfset mac.init(key)>
<cfset mac.update(messageBytes)>
<cfreturn mac.doFinal()>
</cffunction>
Вывод вывода этой функции не дает никаких ошибок, но и не соответствует ожидаемому выводу. Опять же, я был бы очень признателен за любую помощь или подтолкнуть в правильном направлении. Я думаю, что часть моей проблемы заключается в том, как я кодирую ключ и строку URL, но я не уверен. Спасибо всем заранее!
1 ответ
key.init(keyBytes,"HmacSHA512")
Почти. Этот UDF жестко запрограммирован для использования "HmacSHA512". Измените его на "HmacSHA1", или, что еще лучше, сделайте его параметром функции, таким как "encoding".
Пример:
<cfset action = "http://membersuite.com/contracts/IConciergeAPIService/WhoAmI">
<cfset associationId = "00000000-0000-0000-0000-000000000000">
<cfset sessionId = "11111111-1111-1111-1111-111111111111">
<cfset stringToSign = action & associationId & sessionId>
<cfset key = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==">
<cfset result = binaryEncode(hmacEncrypt(key, stringToSign, "US-ASCII"), "base64")>
<cfset writeDump(result)>
Результат:
2zsMYdHb/MJUeTjv5cQl5pBuIqU=
NB: Начиная с CF10 +, HMAC теперь является основной функцией:
<cfset resultAsHex = hmac(stringToSign, binaryDecode(key, "base64"), "hmacsha1", "us-ascii")>
<cfset resultAsBase64 = binaryEncode(binaryDecode(resultAsHex, "hex"), "base64")>
<cfset writeDump(resultAsBase64)>