Преобразование функций PHP OpenSSL в Python - PullRequest
0 голосов
/ 21 января 2019

Мне нужна помощь в преобразовании генератора сигнатур API Walmart из PHP в Python. Я все еще немного новичок в PHP и Python (хотя я быстро учусь), но чтобы использовать API разработчика Walmart (НЕ открытый API), вам, очевидно, нужно знать, как работает криптография, поэтому я немного застрял.

Вот оригинальный код PHP от https://developer.walmart.com/#/apicenter/contentProvider#introduction:

$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-код Walmart, так как они случайно закомментировали строку, в которой находится оператор if. Кроме того, они base64_decode закрытый ключ Walmart, а затем сразу 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 ...?

У меня проблемы с поиском / пониманием Python-эквивалента openssl_pkey_get_private и openssl_sign. Часть кода $ Hash выглядит так, будто она просто проверяет, знает ли PHP, что такое sha256, или проверяет, какое имя оно использует? Правильно?

Должен ли я понять, что openssl_pkey_get_private берет ключ (который я только что вручную преобразовал в определенный формат) и возвращает закрытый ключ, который сопряжен с этим исходным ключом (поэтому Walmart может, при наличии того же ключа, получить тот же ключ и подтвердите, кто запрашивает данные)?

openssl_sign Я думаю, я понимаю. Он генерирует подпись, когда ему передаются указанные данные (те же данные, которые будут отправлены в заголовке с запросом API, в сочетании с закрытым ключом, так как именно они проверяют, кто запрашивает данные?). Опять же, я все еще не уверен, как это сделать в Python.

Любая помощь будет принята с благодарностью. Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...