我搜索並發現了幾個問題,這些問題解決了我正在努力完成的任務,但我似乎無法完全明白這一點。我是編程新手,正試圖複製供應商提供給我的少量代碼(PHP,Ruby,Perl,C#)。我已經採用了PHP代碼,並盡我所能在Python中複製它,並且除了這個簽名函數以外,已經完成了所有工作。基本上,我必須獲取用戶通過Web表單傳入的數據,對其進行簽名,然後將其發送給Web服務偵聽器進行處理。儘可能地嘗試,我不能得到簽名值匹配。不幸的是,供應商不提供代碼級別的支持,除了他們的樣品,所以我在那裏運氣不好。這裏的PHP示例:Python HMAC-SHA256簽名不同於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);
}
?>
被調用爲這樣:
<?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已經用於試圖複製:
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()方法返回的對象中:
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代碼中搞亂,但似乎沒有奏效。提前致謝!
爲什麼b64encode是十六進制的? Facebook不希望你,爲一。 參見https://github.com/pythonforfacebook/facebook-sdk/commit/157799da3bb725b6b2f8698f7ee53b4d0e2abf2c其使用 hmac.new(app_secret.encode( 'ASCII'), 味精= access_token.encode( 'ASCII'), digestmod = hashlib.sha256).hexdigest() – drewp