将PHP OpenSSL函数转换为Python

时间:2019-01-21 17:18:59

标签: php python python-3.x openssl

我需要一些帮助,将Walmart的API签名生成器从PHP转换为Python。我对PHP和Python还是有点陌生​​(尽管我学得很快),但是要使用沃尔玛的开发人员API(不是开放API),您显然需要了解加密技术的工作原理,所以我有些困惑。

这是来自https://developer.walmart.com/#/apicenter/contentProvider#introduction的原始PHP代码:

$URL = //Walmart API URL along with path and query parameters
$RequestMethod = //Request method type i.e GET, POST
$Timestamp = round(microtime(true) * 1000); //Current system timestamp
function _GetWalmartAuthSignature($URL, $RequestMethod, $Timestamp) {
  $WalmartPrivateKey = //Your Walmart Private Key;
  $WalmartConsumerID = //Your Walmart Comsumer Id;
  // CONSTRUCT THE AUTH DATA WE WANT TO SIGN
  $AuthData = $WalmartConsumerID."\n";
  $AuthData .= $URL."\n";
  $AuthData .= $RequestMethod."\n";
  $AuthData .= $Timestamp."\n";
  // GET AN OPENSSL USABLE PRIVATE KEY FROMM THE WARMART SUPPLIED SECRET
  $Pem = _ConvertPkcs8ToPem(base64_decode($WalmartPrivateKey));
  $PrivateKey = openssl_pkey_get_private($Pem);
  // SIGN THE DATA. USE sha256 HASH
  $Hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256";
  if (!openssl_sign($AuthData, $Signature, $PrivateKey, $Hash))
  { 
    // IF ERROR RETURN NULL
    return null;
  }
  //ENCODE THE SIGNATURE AND RETURN
  return base64_encode($Signature);
}
function _ConvertPkcs8ToPem($der)
{
  static $BEGIN_MARKER = "-----BEGIN PRIVATE KEY-----";
  static $END_MARKER = "-----END PRIVATE KEY-----";
  $key = base64_encode($der);
  $pem = $BEGIN_MARKER . "\n";
  $pem .= chunk_split($key, 64, "\n");
  $pem .= $END_MARKER . "\n";
  return $pem;
}

我完全不相信沃尔玛的PHP代码,因为他们不小心将if语句所在的行注释掉了。此外,他们对Walmart私钥进行base64_decode编码,然后立即再次对其进行base64_encode编码……这有什么意义?

无论如何,这是我在Python中想到的:

import base64
import time

# Request URL
url = 'https://developer.walmart.com/orderProxy/order-api-doc-app/rest/v3/orders?createdStartDate=2018-12-01&createdEndDate=2018-12-07&limit=10'
request_method = 'GET'
timestamp = int(time.time() * 1000)
walmart_private_key = '**redacted**'
walmart_consumer_id = '**redacted**'

# Construct auth_data for signature.
auth_data = walmart_consumer_id + "\n"
auth_data += url + "\n"
auth_data += request_method + "\n"
auth_data += str(timestamp) + "\n"

# Convert private key from PKCS8 to PEM (without using a new function)
# The original PHP says to decode, and then immediately re-encode the private key ... so I'm skipping that ...?
pem_start = "-----BEGIN PRIVATE KEY-----\n"
key_chunk = [walmart_private_key[i:i+64] for i in range(0,len(walmart_private_key), 64)]
pem_end = "\n-----END PRIVATE KEY-----\n"
pem = pem_start + "\n".join(key_chunk) + pem_end

# openssl_pkey_get_private, but with Python ...?

# openssl_sign, but with Python ...?

我在查找/理解openssl_pkey_get_private和openssl_sign的Python等效项时遇到了麻烦。 代码的$ Hash部分似乎只是在检查PHP是否知道sha256是什么,还是在检查其使用的名称?对吧?

我是否了解openssl_pkey_get_private需要一个密钥(我刚刚将其手动转换为某种格式),并返回了一个与原始密钥配对的私有密钥(因此,沃尔玛可以在给定相同密钥的情况下到达相同的密钥并确认谁在请求数据)?

openssl_sign我想我明白。当给定指定的数据时,它将生成一个签名(将与API请求一起发送到标头中的相同数据,再加上私钥,因此这就是他们验证谁要求数据​​的方式)。同样,尽管如此,我仍然不确定如何在Python中做到这一点。

任何帮助将不胜感激。谢谢。

0 个答案:

没有答案