2016-10-03 2 views
1

J'essaie d'utiliser la fonction hmac() de ColdFusion pour calculer la valeur HMAC en utilisant binaryEncode (binaryObj, 'Base64') au lieu de toBase64 car toBase64 est en train d'être déprécié. Cela fonctionne parfaitement avec toBase64() mais pas avec binaryEncode(). Les docs ne sont pas très informatifs. Quelqu'un peut-il m'aider à comprendre pourquoi je ne peux pas obtenir la même valeur en utilisant binaryEncode? D'après ce que je comprends, la fonction hmac() retourne les résultats au format hexadécimal. BinaryEncode() attend une valeur binaire, donc les résultats de hmac() doivent d'abord être convertis de Hex en Binary afin qu'il puisse passer de Binary à Base64.ColdFusion hmac() renvoie différentes valeurs avec toBase64 et binaryEncode

<cfset string = "1234567890" /> 
<cfset secretKey = "abcdefghijklmnopqrstuvwxyz" /> 
<!--- Get Hex results from HMAC() ---> 
<cfset hmacHex = hmac(string,secretKey,'HMACSHA256') /> 
<!--- Decode the binary value from hex ---> 
<cfset hmacAsBinary = binaryDecode(hmacHex,'hex') /> 
<!--- Convert binary object to Base64 ---> 
<cfset hmacBase64 = binaryEncode(hmacAsBinary, 'base64') /> 
<cfoutput> 
    <!--- incorrect hmac signature ---> 
    hmacBase64: #hmacBase64#<br> 
    <!--- correct hmac signature ---> 
    toBase64: #toBase64(hmac(string,secretKey,'HMACSHA256'))#<br> 
</cfoutput> 

Les résultats sont les suivants:

hmacBase64: VEVGNnqg9b0eURaDCsA4yIOz5c+QtoJqIPInEZOuRm4= 
toBase64: NTQ0NTQ2MzY3QUEwRjVCRDFFNTExNjgzMEFDMDM4Qzg4M0IzRTVDRjkwQjY4MjZBMjBGMjI3MTE5M0FFNDY2RQ== 

Une chose que je remarque est que les résultats sont beaucoup plus lorsque vous utilisez le toBase64. Je n'arrive pas à comprendre pourquoi je ne peux pas utiliser binaryEncode. Je voudrais depuis toBase64 est déprécié. Toute idée est très appréciée. Merci!

Répondre

3

mise à jour en fonction des commentaires:

bien en utilisant ToBase64(Hmac(...)) est pas la bonne façon de convertir une chaîne hexagonale pour base64 ;-) Cependant, il semble que l'API exige autre chose qu'une conversion droite. Si c'est le cas, faites simplement ce que fait le code ToBase64(hmac(...)). à-dire Decode la chaîne hexagonale comme UTF8 et recoder comme base64:

matchingResult = binaryEncode(charsetDecode(hmacHex, "utf-8"), "base64")


Réponse courte:

Les deux méthodes sont totalement différentes valeurs de codage. C'est pourquoi les résultats ne correspondent pas. La méthode correcte pour convertir la chaîne hexadécimale en base64 utilise BinaryEncode/Decode().

Deuxième réponse:

<!--- correct hmac signature --->
toBase64: #toBase64(hmac(string,secretKey,'HMACSHA256'))#<br>

En fait, c'est pas la bonne façon de convertir hex à base64.

Hexadécimal et Base64 sont juste différentes façons de représenter une valeur binaire. Pour obtenir les mêmes résultats, les deux méthodes doivent commencer par le même binaire. Dans ce cas, codent réellement des valeurs totalement différentes. D'où la différence dans les résultats. Avec une chaîne hexadécimale, chaque octet est représenté par deux caractères.

Donc, le binaire sera moitié la taille de la chaîne d'origine. Dans le cas de HMAC (HMACSHA256), la chaîne hexadécimale résultante a une longueur de 64 caractères. La valeur binaire doit donc être de 32 octets.Pour obtenir la valeur binaire correcte, la chaîne doit être décodé comme hex:

original string length = #len(hmacHex)# 
binary size = #arrayLen(binaryDecode(hmacHex, "hex"))# 

Le problème avec ToBase64 est qu'il décode la chaîne de manière incorrecte. Il traite l'entrée comme UTF8 et décode les caractères dans la chaîne individuellement. Donc la valeur binaire est le double de la taille qu'elle devrait être. Notez qu'il s'agit de 64 octets, au lieu de 32? C'est pourquoi la chaîne finale est plus longue aussi.

UTF8 binary size = #arrayLen(charsetDecode(hmacHex, "utf-8"))# 
ToBase64 binary size = #arrayLen(binaryDecode(toBase64(hmacHex), "base64"))# 

Encore une fois, les deux méthodes produisent des résultats différents car elles codent des valeurs totalement différentes. Cependant, à proprement parler, seule la première méthode est correcte. Pour réencoder une chaîne hexadécimale en tant que base64, utilisez binaryEncode/binaryDecode:

correctResult = binaryEncode(binaryDecode(hmacHex, "hex"), "base64") 
+0

Merci pour la réponse Leigh. Bien que je ne puisse pas dire avec certitude ce qui est bien ou mal, je peux dire que les résultats eux-mêmes semblent désactiver l'utilisation de binaryEncode/binaryDecode avec la fonction hmac() de CF. Je pense que quelque chose est incorrect dans ColdFusion ou la façon dont je le convertis de Hex en Binaire en Base64. Notre processeur de paiement fait des intégrations avec des milliers d'entreprises et il correspond aux résultats toBase64(). De plus, nous l'avons configuré en PHP en utilisant hash_hmac et base64_encode, et il correspond aux résultats de toBase64() de CF. Ces deux choses donnent l'impression que le problème est avec binaryEncode/Decode avec cf hmac(). – billvsd

+0

Je devrais noter que j'ai été en mesure d'obtenir une valeur de signature hmac() en utilisant HMACSHA1, cependant, en utilisant HMACSHA256 ne correspond pas à notre fournisseur de paiement ni PHP comme prévu. – billvsd

+1

Eh bien les règles individuelles pour un processeur de paiement et ce dont ils ont besoin est une histoire totalement différente ;-) Cependant, ce n'est * pas * la bonne façon de convertir de hex à base64. Cela dit, si c'est ce que leur API nécessite, faites juste ce que j'ai expliqué ci-dessus. Décoder l'hexagone comme UTF8 et le ré-encoder comme base64: 'binaryEncode (charsetDecode (hmacHex," utf-8 ")," base64 ")' – Leigh