首页 > 解决方案 > Convert HMAC Hash from Python to PHP

问题描述

Im trying to convert a Python script to PHP and I have trouble getting the same hmac hash values (hmac_signature).

Python script:

import hashlib
import hmac
import json
#Pre shared secret key
secret = "cd01985/813hip914Vnn04&1#11ai761"
#The message I will send
message = {"user_id": "Frank", "query": "Dog"}
#Output message: {'user_id': 'Frank', 'query': 'Dog'}
#Encode the secret using UTF-8
secret_encoded = secret.encode('utf-8')
#Output secret_encoded: b'cd01985/813hip914Vnn04&1#11ai761'
#Dump dict to string and encode using UTF-8
message_encoded = json.dumps(message).encode('utf-8')
#Output messag_encoded: ab742454c0158c3ec8d8c9c8965381567d45bee77e6f8d9aacb2239587285f87
#Compute the HMAC hash and convert to string of hex chars
hmac = hmac.new(secret_encoded, message_encoded, hashlib.sha256)
#Output hmac: <hmac.HMAC object at 0x000001E05BE4BE50>
hmac_signature = hmac.hexdigest()
#Output hmac_signature: ab742454c0158c3ec8d8c9c8965381567d45bee77e6f8d9aacb2239587285f87

PHP:

<?php
    //Pre shared secret key
    $secret = "cd01985/813hip914Vnn04&1#11ai761";
    //The message I will send
    $message = array(
        'user_id'=>"Frank",
        'query'=>"Dog"                              
    );
    //Output $message: Array ( [user_id] => Frank [query] => Dog )
    //Encode the secret using UTF-8
    $secret_encoded = utf8_encode($secret);
    //Output $secret_encoded: cd01985/813hip914Vnn04&1#11ai761
    //Dump dict to string and encode using UTF-8
    $message_encoded = json_encode($message);
    //Output $message_encoded: {"user_id":"Frank","query":"Dog"}
    $message_encoded = utf8_encode($message_encoded);
    //Output $message_encoded: {"user_id":"Frank","query":"Dog"}
    //Compute the HMAC hash and convert to string of hex chars
    $hmac_signature = hash_hmac('sha256', $message_encoded, $secret_encoded, false);
    //Output $hmac_signature: e4fd77b03cd58b174c3f6f0ad52a484386280289127f5fa7251df1686c3fb582
?>

Do anyone know why im getting different hash?

Edit1: What is json.dumps(message) converted into PHP, json_encode($message) dont give me same output?

标签: pythonphphmac

解决方案


我尝试了您的代码,并message_encoded在 Pythonb'{"query": "Dog", "user_id": "Frank"}'中为我返回。

与 PHP 的区别在于 Python 中可以避免的空格

message_encoded = json.dumps(message, separators=(",", ":")).encode('utf-8')

然后结果hmac_signature与 PHP 中的相同。

请注意,您必须使用 Python 3.7 或更高版本来确保键中的键顺序与文字dict中给出的顺序相同。dict


推荐阅读