2

I'm working on a suitescript to integrate NetSuite with the Walmart Marketplace APIs. And, as the another OP here says it right their documentation pretty much says if you don't use Java you're on your own.

I'm looking for a way to do the same either in suitescript or javascript.

Instruction from Walmart's API documentation:

Sign the byte array representation of this data by:

Decoding the Base 64, PKCS-8 representation of your private key. Note that the key is encoded using PKCS-8. Libraries in various languages offer the ability to specify that the key is in this format and not in other conflicting formats such as PKCS-1. Use this byte representation of your key to sign the data using SHA-256 With RSA. Encode the resulting signature using Base 64.

And, a java code from their documentation to do the same:

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

For reference, here's the similar thing asked for dot net. Any help would be appreciated.

Community
  • 1
  • 1
Haxvik
  • 21
  • 1
  • 1
    Please re-tag from JavaScript to Java. – evolutionxbox Feb 23 '17 at 13:13
  • I think I am seeking for any help either in javascript or Netsuite only. The java code I've provided is just for reference. So this should be tagged to javascript only. Please correct if I'm wrong. – Haxvik Feb 24 '17 at 11:30

2 Answers2

1

I tried developing a SAML connector in Javascript once and found several libraries that deal with different key file formats etc. I got fairly far along but the time to run some of the scripts was incredible (imagine trying to login but the process taking two minutes to decide your login was valid)

At that point I switched to an external system and managed the SSO with Netsuite's inbound SSO.

It doesn't look like things have improved that much with NS in the crypto department even with SS 2.0.

I'd tend to package this into two parts. Generate your files in Suitescript and pass them through a java based web service that handles the signing requirements. Minimizes the amount of Java you have to write and keeps your transaction extraction/formatting scripts under easy control.

bknights
  • 14,408
  • 2
  • 18
  • 31
  • Yes, a Java web service can do the job, but it requires additional server/VM to host it. If I don't get any other solution in javascript or suitescript, I'll probably have to convince the client for the same. Thanks! – Haxvik Feb 24 '17 at 11:41
  • Enough infrastructure to run this is pretty inexpensive these days. EC2,linode,Heroku,possibly lambda allows Java. Any of those would also let you do this in node – bknights Feb 24 '17 at 14:29
0

I found a library (jsrsasign) that will do the Walmart signature from NetSuite server side in under 4 seconds! (Marketplace has gone to OAuth2, but I'm stuck with signing as a Drop Ship Vendor)

/**
 *@NApiVersion 2.x
 *@NScriptType ScheduledScript
 */

define(['N/log', 'N/https', '../lib/jsrsasign-master/jsrsasign-all-min'],
    function(log, https) {
        function execute(context) {
            var pkcs8Der = {Your Walmart Private Key};
            var pkcs8Pem = [
                '-----BEGIN PRIVATE KEY-----',
                pkcs8Der.match(/.{0,64}/g).join('\n'),
                '-----END PRIVATE KEY-----'
            ].join('\n');

            var tStamp = Date.now()
            var stringToSign = [
                tStamp,
                {Your Walmart Comsumer Id},
                {Request URL},
                {Request Method (All Caps)}
            ].join('\n') + '\n';

            var sig = new KJUR.crypto.Signature({"alg": "SHA256withRSA"});
            sig.init(pkcs8Pem);
            var sigVal = hextob64(sig.signString(stringToSign));

            log.audit({title: 'Signature', details: sigVal});
            log.audit({title: 'Timestamp', details: tStamp});
        }

        return {
            execute: execute,
        };
    }
);

I had to add the following code to the jsrsasign-all-min.js library file for the Scheduled Script to load the module:

var navigator = {}, window = undefined;
Nathan Sutherland
  • 1,191
  • 7
  • 9