2016-11-13 1 views
2

Je travaille sur l'implémentation du Walmart API dans NodeJS. Walmart fournit uniquement des exemples JAVA. J'ai des problèmes pour bien faire les choses. Ma signature est un peu plus longue et n'est pas acceptée par rapport à l'utilisation de l'exécutable Java qu'ils fournissent.Conversion de code cryptographique Java en NodeJS

J'apprécierais toute aide. Même déterminer quel format le Walmart fourni secret serait aiderait.

VOICI travail code Java:

import org.apache.commons.codec.binary.Base64; 
import java.security.KeyFactory; 
import java.security.PrivateKey; 
import java.security.Signature; 
import java.security.spec.PKCS8EncodedKeySpec; 

public class SHA256WithRSAAlgo { 
    private static String consumerId = "b68d2a72...."; // Trimmed for security reason 
    private static String baseUrl = "https://marketplace.walmartapis.com/v2/feeds"; 
    private static String privateEncodedStr = "MIICeAIBADANBgkqhkiG9w0BAQEFAA......";  //Trimmed for security reasons 
    public static void main(String[] args) { 
     String httpMethod = "GET"; 
     String timestamp = String.valueOf(System.currentTimeMillis()); 
     String stringToSign = consumerId + "\n" + 
           baseUrl + "\n" + 
           httpMethod + "\n" + 
           timestamp + "\n"; 
     String signedString = SHA256WithRSAAlgo.signData(stringToSign, privateEncodedStr); 
     System.out.println("Signed String: " + signedString); 
    } 
    public static String signData(String stringToBeSigned, String encodedPrivateKey) { 
     String signatureString = null; 
     try { 
      byte[] encodedKeyBytes = Base64.decodeBase64(encodedPrivateKey); 
      PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(encodedKeyBytes); 
      KeyFactory kf = KeyFactory.getInstance("RSA"); 
      PrivateKey myPrivateKey = kf.generatePrivate(privSpec); 
      Signature signature = Signature.getInstance("SHA256withRSA"); 
      signature.initSign(myPrivateKey); 
      byte[] data = stringToBeSigned.getBytes("UTF-8"); 
      signature.update(data); 
      byte[] signedBytes = signature.sign(); 
      signatureString = Base64.encodeBase64String(signedBytes); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return signatureString; 
    } 
} 

Voici mon code Node:

const PK_HEADER = '\n-----BEGIN PRIVATE KEY-----\n' 
const PK_FOOTER = '\n-----END PRIVATE KEY-----\n' 

const consumerId = 'b68d2a72....' 
const baseUrl = 'https://marketplace.walmartapis.com/v2/feeds' 
const privateEncodedStr = 'MIICeAIBADANBgkqhkiG9w0BAQEFAA......'  

const privateKey = `${PK_HEADER}${config.walmart.secret}${PK_FOOTER}` 

const privateEncodedKey = Buffer.from(privateKey, 'base64') 
const timestamp = Date.now() 

const stringToSign = consumerId + '\n' + 
        baseUrl + '\n' + 
        httpMethod + '\n' + 
        timestamp + '\n' 

const sign = createSign('RSA-SHA256') 
sign.update(stringToSign) 
const signedString = sign.sign(privateKey, 'hex') 

console.log(signedString) 

Quelques notes. J'ai essayé de passer le privateEncodedStr tel quel mais Crypto rechigne à ne pas avoir les en-têtes PEM donc j'ai dû les ajouter.

En utilisant la même horodatage le code Java a produit quelque chose comme:

bhG0q4Es7iOJtBvepJ2Ao6zPRllf6nM+026dgEadPcaYDdIoCQBYxWWSXB16XcQXgCDcqZ1PW2xgAavHC57jchSXtsTYkuXcWBavQGTH+5YonxIJCzI0wimVKKbqtocKvz4sngXKvIDP7wKKUdXOT6zXVYOdjLfUTERTs7RVg= 

Mon code JS:

219af9f3048ccef558d6ddeeb61d19ed8a968ade5125760d81717dbd62e8447dd831b123a52624d56bc35aef1b082c29585e6fece2aba0fb7853d6840f45e724489028415a9eab8a51e48037a5884f5a12a238ed61a16003e1c412f873d3cfd2f6336dec8c262b01c3ba2a234f0979b8073f096cd35c7d1425bbcfc4603ff05b 

Voici ce que le secret Walmart ressemble un peu:

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMCCJeju5NFCHc/53N0AjZnmWq0UYZyrh3jRZH3UAISeZmLxcAgO65Cg8SfRact172Iy1uYnCB4NqKT5+x0BelWHA2fci5/7VqAdTJ3iZWB1g61lLUpf0IiesMWAycMBf7GwaVIsCGoPb+IC6l1P5IV2Mtb29WnivQyE3UM4dLvCvejdyPq8IoBIywTAgMBAAECgYEAnZ7yo1JXD+9usYcIC/wT9Nrji6uQcNMRTR9FhLE861k2w/Sjok0kzepZjanNojgwQS6OWIy3VEkRj2bTO7N4s6ApLa8yxoQt6ZrOSId9Ut7IenZQ39c6c/ig6e+awyjGvJlKdf7wtv2i4l4tiL8w23RnSECQQDy0wugM5hzV5wc/ejj+9cB8cqdEjfFG8yBZ200W1DAQwepIWFqSdiHbHW9xX5SiFa7JsDHyFWSdboYQToRDHuVAkEAyvQwDqAAz/FJn9oFKXznMjFfrtfoZ/BPrc/4BOUiyWjitxE6Ia5rNuTgCq3u1XxxP78t5spzMr5H5QdoUFHfBwJAbqpYZg6dsBOBhoUBmsWv26cyyOCEg4h9113oDh3MBPEXcQJAHd2JJN3OwMrU9rzyfYRv0ScK2YPUI1dtojo0WSQr2UafYTCCnEstN5vPvDoSvwXO1myk0COs1kAAbveHMIsf1jKVx7euXYP1J8Zwdfd9FjS2CQJAZ8L+jQyGlYIIdUQA7n0bbUblsGntsk1RKkTuZ31Q4w5gBnKO4dk3WMVhNdhmJnZRHRNflA41TITLNYh0EnrWheadVrhpBm2YBn7WFPQ== 

Tous idée quel format c'est? Il semble être un private key avec les en-têtes/pieds de page retirés.

+0

Ceci est un peu sans rapport, mais si vous le comprenez, seriez-vous en mesure de poster sur github? à votre santé! –

+0

Votre chaîne JS résultante semble être une séquence d'octets hexadécimaux, tandis que la chaîne Java générée est encodée dans 'base64'. Essayez 'console.log (nouveau Buffer (signedString, 'hex'). ToString ('base64'))' – karliwson

+0

@karuzo vous êtes mon héros! c'était ça. Pourriez-vous afficher cela comme réponse s'il vous plaît? – cyberwombat

Répondre

1

Votre code est exact, vous avez juste besoin de sortir signedString dans le bon format, qui est base64.

Tout changement:

const signedString = sign.sign(privateKey, 'hex');

Pour:

const signedString = sign.sign(privateKey, 'base64');

Et là vous allez.

+0

Et voici le Gist https://gist.github.com/cyberwombat/bc22fcd44037b7f8c1920432636f9cd5 – cyberwombat