WM_SEC.AUTH_SIGNATURE PHP 示例

问题描述

Walmart 提供了一个 Java 示例来生成新 api 所需的签名:

使用私钥生成的签名,并对消费者 ID、时间戳和密钥版本的值进行签名。此签名的 TTL 为 180 秒。发布后,API 代理将抛出“时间戳已过期”错误

Java 代码

//package com.walmart.platform.common;

import java.io.ObjectStreamException;
import java.security.KeyRep;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.sortedSet;
import java.util.TreeSet;

import org.apache.commons.codec.binary.Base64;

public class SignatureGenerator {

    public static void main(String[] args) {
        SignatureGenerator generator = new SignatureGenerator();

        String consumerId = "XXXXXXXXXXX";
        String priviatekeyversion = "1";
        String privateKey = "XXXXXXXXXXX";

        long intimestamp = System.currentTimeMillis();

        System.out.println("consumerId: " + consumerId);
        System.out.println("intimestamp: " + intimestamp);

        Map<String,String> map = new HashMap<>();
        map.put("WM_CONSUMER.ID",consumerId);
        map.put("WM_CONSUMER.INTIMESTAMP",Long.toString(intimestamp));
        map.put("WM_SEC.KEY_VERSION",priviatekeyversion);

        String[] array = canonicalize(map);

        String data = null;

        try {
            data = generator.generateSignature(privateKey,array[1]);
        } catch(Exception e) { }
        System.out.println("Signature: " + data);
    }
    public String generateSignature(String key,String stringToSign) throws Exception {
        Signature signatureInstance = Signature.getInstance("SHA256WithRSA");

        ServiceKeyRep keyRep = new ServiceKeyRep(KeyRep.Type.PRIVATE,"RSA","PKCS#8",Base64.decodeBase64(key));

        PrivateKey resolvedPrivateKey = (PrivateKey) keyRep.readResolve();

        signatureInstance.initSign(resolvedPrivateKey);

        byte[] bytesToSign = stringToSign.getBytes("UTF-8");
        signatureInstance.update(bytesToSign);
        byte[] signatureBytes = signatureInstance.sign();

        String signatureString = Base64.encodeBase64String(signatureBytes);

        return signatureString;
    }
    protected static String[] canonicalize(Map<String,String> headersToSign) {
        StringBuffer canonicalizedStrBuffer=new StringBuffer();
        StringBuffer parameterNamesBuffer=new StringBuffer();
        Set<String> keySet=headersToSign.keySet();

        // Create sorted key set to enforce order on the key names
        SortedSet<String> sortedKeySet=new TreeSet<String>(keySet);
        for (String key :sortedKeySet) {
            Object val=headersToSign.get(key);
            parameterNamesBuffer.append(key.trim()).append(";");
            canonicalizedStrBuffer.append(val.toString().trim()).append("\n");
        }
        return new String[] {parameterNamesBuffer.toString(),canonicalizedStrBuffer.toString()};
    }

    class ServiceKeyRep extends KeyRep  {
        private static final long serialVersionUID = -7213340660431987616L;
        public ServiceKeyRep(Type type,String algorithm,String format,byte[] encoded) {
            super(type,algorithm,format,encoded);
        }
        protected Object readResolve() throws ObjectStreamException {
            return super.readResolve();
        }
    }
}

有人有 PHP 等价物吗?

解决方法

在论坛上发帖时,请屏蔽消费者 ID 和私钥。请重新生成一个新的。

关于你的问题,用这个 https://github.com/fillup/walmart-auth-signature-php/blob/master/src/Signature.php