2016-11-13 1 views
2

NodeJS에 Walmart API을 구현하고 있습니다. 월마트는 JAVA 예제 만 제공합니다. 문제가 올바르게 발생합니다. 그들이 제공하는 Java 실행 파일을 사용할 때와 비교할 때 내 서명은 조금 더 길고 받아 들여지지 않습니다.Java 암호화 코드를 NodeJS로 변환

어떤 도움을 주셔서 감사합니다. 심지어 Walmart가 제공 한 형식이 무엇인지 알아내는 것도 도움이 될 것입니다.

여기서 일하고 자바 코드 :

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) 

일부 노트 :

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; 
    } 
} 

여기 내 노드 코드입니다. 나는 privateEncodedStr을 그대로 통과 시키려고했지만 Crypto는 PEM 헤더가 없기 때문에 Boss를 추가하여 추가해야했습니다. 자바 코드 같은 것을 굴복 동일한 타임 스탬프를 사용하여

는 :

bhG0q4Es7iOJtBvepJ2Ao6zPRllf6nM+026dgEadPcaYDdIoCQBYxWWSXB16XcQXgCDcqZ1PW2xgAavHC57jchSXtsTYkuXcWBavQGTH+5YonxIJCzI0wimVKKbqtocKvz4sngXKvIDP7wKKUdXOT6zXVYOdjLfUTERTs7RVg= 

내 JS 코드 :

여기
219af9f3048ccef558d6ddeeb61d19ed8a968ade5125760d81717dbd62e8447dd831b123a52624d56bc35aef1b082c29585e6fece2aba0fb7853d6840f45e724489028415a9eab8a51e48037a5884f5a12a238ed61a16003e1c412f873d3cfd2f6336dec8c262b01c3ba2a234f0979b8073f096cd35c7d1425bbcfc4603ff05b 

는 월마트의 비밀이 좀 보이는 무엇을 좋아 :

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

하나를 이것이 어떤 형식인지 생각해보십시오. 머리글/바닥 글을 제거한 private key 인 것으로 보입니다.

+0

이것은 조금 관련이 없지만 github에 게시 할 수 있다고 생각한다면? 건배! –

+0

결과 JS 문자열은 16 진수 바이트 시퀀스 인 반면 Java 생성 된 문자열은'base64'로 인코딩됩니다. 'console.log (새로운 버퍼 (signedString, 'hex'). toString ('base64'))' – karliwson

+0

@ karuzo 당신은 내 영웅입니다! 그거였다. 답변을 올리시겠습니까? – cyberwombat

답변

1

코드가 맞으면 signedString을 적절한 형식 (base64)으로 출력하면됩니다.

그냥 변화 :

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

사람 :

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

그리고 거기 당신은 간다.

+0

다음은 요점입니다. https://gist.github.com/cyberwombat/bc22fcd44037b7f8c1920432636f9cd5 – cyberwombat