Python HMAC-SHA256签名与PHP签名不同 [英] Python HMAC-SHA256 signature differs from PHP signature

查看:405
本文介绍了Python HMAC-SHA256签名与PHP签名不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索并发现了一些问题,这些问题可以解决我要完成的任务,但是我似乎不太能理解这一点.我是编程新手,正在尝试用几种语言(PHP,Ruby,Perl,C#)复制供应商可以提供给我的一些代码.我已经采用了PHP代码,并尽力将其复制到Python中,并使除此签名功能之外的所有功能均正常工作.基本上,我必须获取用户通过Web表单传递的数据数组,对其进行签名,然后将其发送到Web服务侦听器进行处理.尽我所能,我无法获得匹配的签名值.不幸的是,该供应商除了提供示例外,不提供任何代码级支持,因此我很不走运.这是PHP示例:

I searched and found a few questions that sort of addressed what I am trying to accomplish, but I can't seem to quite put my finger on this. I'm new to programming and am trying to replicate a bit of code that's available to me by the vendor in a handful of languages (PHP, Ruby, Perl, C#). I've taken the PHP code and tried my best to replicate it in Python and have gotten everything working except this signature function. Basically, I have to take an array of data that's being passed in by a user via web form, sign it, and send it to the web services listener to process. Try as I might, I can't get the signature values to match. The vendor unfortunately does not provide code-level support for anything other than their samples, so I'm out of luck there. Here's the PHP sample:

<?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);
}

?>

按如下方式调用:

<?php
foreach($params as $name => $value) {
    echo "<input type=\"text\" id=\"" . $name . "\" name=\"" . $name . "\" value=\"" . $value . "\"/>\n";
}

echo "<input type=\"text\" id=\"signature\" name=\"signature\" value=\"" . sign($params) . "\"/>\n";
?>

这是我在Python中尝试复制的内容:

This is what I've used in Python to attempt to replicate:

def payment_confirmation(self, *args, **kw):
vars = cherrypy.request.params #takes POST parameters from previous page
del vars['submit'] #removed so it doesnt get signed - part of POST from prev. page

def sign_data(vars):
    for key, value in vars.iteritems():
        yield "%s=%s," % (key, value)

sign_payload = ''.join(sign_data(vars)).rstrip(',')
sign_signature = hashlib.sha256(sign_payload + secret_key).digest().encode('base64')

这是我要签名的数据示例(简化为Python代码中通过sign_data()方法返回的对象:

Here's a sample of the data I'm trying to sign (reduced into the object that's being returned via the sign_data() method in the Python code:

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代码中解决这个问题,但是似乎没有用.预先感谢!

I realize it's a long-shot, but does anyone see anything that's obviously incorrect about my signature method in Python vs. the provided method in PHP? I thought it could be a way that the PHP function is encoding the key-value pairs so I tried messing around with that in the Python code but it doesn't seem to have worked. Thanks in advance!

推荐答案

如果您仍然遇到这个问题,不妨尝试使用:

In case you're still stuck on that question, you might want to try using:

sign_signature = base64.b64encode(hmac.new(secret_key, sign_payload, hashlib.sha256).hexdigest())

此处的关键是使用hexdigest()而不是digest().

The key here is to use hexdigest() instead of digest().

在我的案例中,我花了2个小时才弄清楚为什么在尝试使用其新的应用程序秘密证明"对Facebook API请求进行签名时,Python无法产生与PHP相同的结果.

In my case I lost 2 hours finding out why Python did not produce the same result as PHP did when trying to sign Facebook API requests with their new "app secret proof".

这篇关于Python HMAC-SHA256签名与PHP签名不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆