Python HMAC-SHA256签名不同于PHP签名

Python HMAC-SHA256签名不同于PHP签名,python,signature,hmac,Python,Signature,Hmac,我搜索并发现了一些问题,这些问题在某种程度上解决了我试图完成的任务,但我似乎不能完全指出这一点。我是编程新手,正在尝试用几种语言(PHP、Ruby、Perl、C#)复制供应商提供给我的一些代码。我已经使用了PHP代码,并尽我最大的努力在Python中复制它,除了这个签名函数之外,其他一切都正常工作。基本上,我必须获取用户通过web表单传入的数据数组,对其进行签名,然后将其发送到web服务侦听器进行处理。尽管我可能会尝试,但我无法获得匹配的签名值。遗憾的是,该供应商除了其示例之外,没有提供任何代码

我搜索并发现了一些问题,这些问题在某种程度上解决了我试图完成的任务,但我似乎不能完全指出这一点。我是编程新手,正在尝试用几种语言(PHP、Ruby、Perl、C#)复制供应商提供给我的一些代码。我已经使用了PHP代码,并尽我最大的努力在Python中复制它,除了这个签名函数之外,其他一切都正常工作。基本上,我必须获取用户通过web表单传入的数据数组,对其进行签名,然后将其发送到web服务侦听器进行处理。尽管我可能会尝试,但我无法获得匹配的签名值。遗憾的是,该供应商除了其示例之外,没有提供任何代码级支持,因此我在这方面运气不佳。以下是PHP示例:

<?php

define ('HMAC_SHA256', 'sha256');
define ('SECRET_KEY', 'secret_key_redacted');

function sign ($params) {
  return signData(buildDataToSign($params), SECRET_KEY);
}

function signData($data, $secretKey) {
    return base64_encode(hash_hmac('sha256', $data, $secretKey, true));
}

function buildDataToSign($params) {
        $signedFieldNames = explode(",",$params["signed_field_names"]);
        foreach ($signedFieldNames as &$field) {
           $dataToSign[] = $field . "=" . $params[$field];
        }
        return commaSeparate($dataToSign);
}

function commaSeparate ($dataToSign) {
    return implode(",",$dataToSign);
}

?>
下面是我试图签名的数据示例(简化为Python代码中通过sign_data()方法返回的对象):

access_key=12345,reference_number=123456789,currency=USD,locale=en,profile_id=1234567,transaction_type=authorization,signed_date_time=2013-07-22T16:30:43Z,amount=25.00,transaction_uuid=0dc4a151-f2ec-11e2-bb29-005056c00008,payment_method=card,signed_field_names=access_key,profile_id,transaction_uuid,payment_token,signed_field_names,signed_date_time,locale,payment_method,transaction_type,amount,reference_number,currency,payment_token=0000000000000000

我意识到这很难实现,但是有人看到我在Python中的签名方法与PHP中提供的方法明显不正确吗?我想这可能是PHP函数对键值对进行编码的一种方式,所以我尝试在Python代码中处理它,但它似乎不起作用。提前感谢

如果您仍然无法回答这个问题,您可能需要尝试使用:

sign_signature = base64.b64encode(hmac.new(secret_key, sign_payload, hashlib.sha256).hexdigest())
这里的关键是使用
hexdigest()
而不是
digest()


在我的例子中,我花了2个小时找出了为什么Python在尝试使用新的“应用程序机密证明”签署Facebook API请求时没有产生与PHP相同的结果。

如果您仍然无法回答这个问题,您可能需要尝试使用:

sign_signature = base64.b64encode(hmac.new(secret_key, sign_payload, hashlib.sha256).hexdigest())
这里的关键是使用
hexdigest()
而不是
digest()


在我的例子中,我花了2个小时找出了为什么Python在尝试用新的“应用程序机密证明”对Facebook API请求进行签名时没有产生与PHP相同的结果。

为什么B64编码hexdigest?Facebook不想让你这样做。比如,看看哪个使用了hmac.new(app_secret.encode('ascii')),msg=access\u-token.encode('ascii'),digesmod=hashlib.sha256)。hexdigest()为什么B64编码一个hexdigest?Facebook不想让你这么做。请查看哪个使用hmac.new(app\u-secret.encode('ascii'),msg=access\u-token.encode('ascii'),digestmod=hashlib.sha256.hexdigest()
sign_signature = base64.b64encode(hmac.new(secret_key, sign_payload, hashlib.sha256).hexdigest())