5

vorrei convertire il seguente frammento di codice Node.JS a JavaScript al fine di eseguire in Google Apps Script:Converti Node.JS frammento di codice di Javascript (Google Apps Script)

Da: Node.JS

function getMessageSignature(path, request, nonce) { 
    var message = querystring.stringify(request); 
    var secret = new Buffer(config.secret, 'base64'); 
    var hash = new crypto.createHash('sha256'); 
    var hmac = new crypto.createHmac('sha512', secret); 
    var hash_digest = hash.update(nonce + message).digest('binary'); 
    var hmac_digest = hmac.update(path + hash_digest, 'binary').digest('base64'); 
    return hmac_digest; 
} 

Questo è il codice che ho provato finora (e molte variazioni di esso):

A: JavaScript/Google Apps script

function getMessageSignature(url, request, nonce) { 

    // Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) 
    //and base64 decoded secret API key 

    const secretApiKey = 'wdwdKswdKKewe23edeYIvL/GsltsGWbuBXnarcxZfu/9PjFbXl5npg=='; 
    var secretApiKeyBytes = Utilities.base64Decode(secretApiKey); 
    var blob = Utilities.newBlob(secretApiKeyBytes); 
    var secretApiKeyString = blob.getDataAsString(); // POTENTIAL ERROR HERE? 

    var json = Utilities.jsonStringify(request); 

    var hash_digest = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, 
     nonce + json); 

    var hmac_digest = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, 
     url + hash_digest, secretApiKeyString); // POTENTIAL ERROR HERE? 

    var base64 = Utilities.base64Encode(hmac_digest); 

    return base64; 
} 

Quando si invia la firma come parte della mia richiesta al server, ho sempre arrivare il messaggio di errore dal server: Invalid Key.

BTW: Questa è l'API che vorrei utilizzare in JavaScript: Kraken API

Gradirei qualsiasi suggerimento o suggerimento molto !!

+0

Ho battuto la testa contro questo per tutta la notte. Si prega di inviare indietro con la soluzione se hai capito. Le funzioni crittografiche in NodeJS e Google App Script sembrano differire in termini di output. –

risposta

2

Un problema è che querystring.stringify non è lo stesso di Utilities.jsonStringify (che, FYI, è deprecato a favore di JSON.stringify).

credo che questo sarà equivalente:

function queryStringify(obj) { 
    var params = []; 
    for(var key in obj) { 
     if(Object.hasOwnProperty(key)) { 
      if(typeof key === 'string') { 
       params.push([key, obj[key]]); 
      } else { 
       obj[key].forEach(function(val) { 
        params.push([key, val]); 
       }); 
      } 
     } 
    } 
    return params.map(function(param) { 
     return encodeURIComponent(param[0]) + '=' + encodeURIComponent(param[1]); 
    }).join('&'); 
} 

Anche se non sono sicuro se questo è il motivo che state vedendo il vostro errore.

+0

Grazie per la tua risposta, Paul! Credo che l'errore sia da qualche altra parte perché ottengo l'errore anche quando "hard codice" la stringa JSONified nella mia richiesta. Credo che il mio problema potrebbe venire da 'url + hash_digest', che è un'operazione di stringa, ma dovrebbe essere un'operazione di byte. – AlexR

+0

@AlexR Qualche fortuna per far funzionare tutto questo? Sto provando a fare la stessa cosa. –

4

Soluzione:

Usa jsSHA (https://github.com/Caligatio/jsSHA/), piuttosto che le funzioni di Google App Script. Crea un nuovo file di codice "jsSHA.gs" in Google App Script e copia/incolla in tutti i file js ottimizzati jsSHA da github.

function getKrakenSignature (path, postdata, nonce) { 
    var sha256obj = new jsSHA ("SHA-256", "BYTES"); 
    sha256obj.update (nonce + postdata); 
    var hash_digest = sha256obj.getHash ("BYTES"); 

    var sha512obj = new jsSHA ("SHA-512", "BYTES"); 
    sha512obj.setHMACKey (api_key_private, "B64"); 
    sha512obj.update (path); 
    sha512obj.update (hash_digest); 
    return sha512obj.getHMAC ("B64"); 
} 

function getKrakenBalance() { 
    var path = "/0/private/Balance"; 
    var nonce = new Date() * 1000; 
    var postdata = "nonce=" + nonce; 

    var signature = getKrakenSignature (path, postdata, nonce); 

    var url = api_url + path; 
    var options = { 
    method: 'post', 
    headers: { 
     'API-Key': api_key_public, 
     'API-Sign': signature 
    }, 
    payload: postdata 
    }; 

    var response = UrlFetchApp.fetch (url, options); 

    // ERROR handling 

    return response.getContentText(); 
} 
+0

Grazie! Ha funzionato davvero per me! – LeandroP

+0

Sei un risparmiatore di vita: occhiolino: – king