Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate WM_SEC.AUTH_SIGNATURE?

Does anyone have python code that can generate this header for the Walmart API?

WM_SEC.AUTH_SIGNATURE

I have tried to wrap my head around the java example but I am not having any luck of it as I have no Java experience.

If anyone knows the format of the string that needs to be signed I could probably figure it out from there.

How do I solve the problem?

like image 396
plugcity Avatar asked Aug 06 '19 20:08

plugcity


2 Answers

Here is the code that I ended up using to get the authorization to work if anyone needs it:

import requests, json, pprint, time
from requests.auth import HTTPBasicAuth
import errno
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
import hashlib
import base64


ACCOUNT_SID = 'xxxxxx'
AUTH_TOKEN = 'xxxxxxxx'
BASE_URL = 'https://products.api.impactradius.com/Mediapartners/{}/'.format(ACCOUNT_SID)
API_PATH = 'Catalogs/4277'
consumerId = 'xxxxxxxx'
epoxTime = str(int(time.time()*1000))
keyVersion = '1'

URL = 'https://developer.api.walmart.com/api-proxy/service/affil/product/v2/items'


hashDict = { 'WM_CONSUMER.ID' : consumerId,
            'WM_CONSUMER.INTIMESTAMP' : epoxTime,
            'WM_SEC.KEY_VERSION' : keyVersion
            }
sortedHashString = hashDict['WM_CONSUMER.ID'] +'\n'+ hashDict['WM_CONSUMER.INTIMESTAMP'] +'\n'+ hashDict['WM_SEC.KEY_VERSION']+'\n'
encodedHashString = sortedHashString.encode()

try:
    with open('./WM_IO_private_key.pem', 'r') as f:
        key = RSA.importKey(f.read())
except IOError as e:
    print(e)

hasher = SHA256.new(encodedHashString)
signer = PKCS1_v1_5.new(key)
signature = signer.sign(hasher)

signature_enc = str(base64.b64encode(signature),'utf-8')

headers = { 'WM_CONSUMER.ID' : consumerId,
            'WM_CONSUMER.INTIMESTAMP' : epoxTime,
            'WM_SEC.AUTH_SIGNATURE' : signature_enc,
            'WM_SEC.KEY_VERSION' : keyVersion,
            'WM_QOS.CORRELATION_ID' : 'afjksldkfj4r8ojfns',
            'WM_IFX.CLIENT_TYPE' : 'INTERNAL',
            'WM_PREVIEW' : 'false',
            'WM_SHOW_REASON_CODES' : 'ALL',
            'Content-Type' : 'application/json',
            }

params = {
            'category' : '4171_1228385',
            'publisherId' : 'xxxxxxxxxxx'
        }

response = requests.get(URL, headers=headers, params=params)

jsonData = json.loads(response.text)
like image 171
plugcity Avatar answered Sep 22 '22 13:09

plugcity


Below example for Affiliates API on PHP

String (message) for sign

$message = self::WM_CONSUMER_ID . "\n" . $milliseconds . "\n" . self::WM_SEC_KEY_VERSION . "\n";

PHP Example class

<?php

declare(strict_types=1);

namespace WalmartBundle\Services;


use phpseclib\Crypt\RSA;

/**
 * Class WalmartAuthSignature
 *
 *  Thanks: https://github.com/fillup/walmart-auth-signature-php/blob/develop/src/Signature.php
 *
 * @package WalmartBundle\Services
 */
class WalmartAuthSignature
{
    public static function sign(string $message, string $privateKey): string
    {
        $rsa = new RSA();

        $decodedPrivateKey = base64_decode($privateKey);
        $rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_PKCS8);
        $rsa->setPublicKeyFormat(RSA::PRIVATE_FORMAT_PKCS8);

        if ($rsa->loadKey($decodedPrivateKey, RSA::PRIVATE_FORMAT_PKCS8)) {
            $rsa->setHash('sha256');
            $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
            $signed = $rsa->sign($message);

            return base64_encode($signed);
        }

        throw new \Exception('Unable to load private key');
    }
}
like image 39
Serge Gorenstein Avatar answered Sep 21 '22 13:09

Serge Gorenstein