Skip to content

Instantly share code, notes, and snippets.

@mrpinghe
Last active Nov 16, 2021
Embed
What would you like to do?
Veracode custom HMAC request signing algorithm (used for API authorization)
var crypto = require('crypto');
const id = process.env.API_ID; // your API ID, reading from environment variable
const key = process.env.KEY; // your API key, reading from environment variable
const preFix = "VERACODE-HMAC-SHA-256";
const verStr = "vcode_request_version_1";
var resthost = "api.veracode.com"; // rest host
var xmlhost = "analysiscenter.veracode.com"; // xml host
var hmac256 = (data, key, format) => {
var hash = crypto.createHmac('sha256', key).update(data);
// no format = Buffer / byte array
return hash.digest(format);
}
var getByteArray = (hex) => {
var bytes = [];
for(var i = 0; i < hex.length-1; i+=2){
bytes.push(parseInt(hex.substr(i, 2), 16));
}
// signed 8-bit integer array (byte array)
return Int8Array.from(bytes);
}
var getHost = (xml) => {
if (xml) {
return xmlhost;
}
return resthost;
}
var generateHeader = (url, method, xml) => {
var host = getHost(xml);
var data = `id=${id}&host=${host}&url=${url}&method=${method}`;
var timestamp = (new Date().getTime()).toString();
var nonce = crypto.randomBytes(16).toString("hex");
// calculate signature
var hashedNonce = hmac256(getByteArray(nonce), getByteArray(key));
var hashedTimestamp = hmac256(timestamp, hashedNonce);
var hashedVerStr = hmac256(verStr, hashedTimestamp);
var signature = hmac256(data, hashedVerStr, 'hex');
return `${preFix} id=${id},ts=${timestamp},nonce=${nonce},sig=${signature}`;
}
module.exports = {
getHost,
generateHeader
}
@mrpinghe

This comment has been minimized.

Copy link
Owner Author

@mrpinghe mrpinghe commented Nov 6, 2018

sample usage

// test.js

const https = require("https");
const auth = require("./auth");

var options = {
    host: auth.getHost(),
    path: "/appsec/v1/applications?size=100&page=0",
    method: "GET"
}

/* xml api

var options = {
    host: auth.getHost("xml"),
    path: "/api/5.0/getapplist.do",
    method: "GET"
}

*/

options.headers = {
    "Authorization": auth.generateHeader(options.path, options.method)
    // xml api
    // "Authorization": auth.generateHeader(options.path, options.method, "xml")
}


var req = https.request(options, (resp) => {
    var body = "";

    resp.on("data", (chunk) => {
        body += chunk;
    });

    resp.on("end", () => {
        console.log(body);
    });
})


req.on("error", (err) => {
    console.error(err);
});

req.end();

Then in command line

$ export API_ID=YOUR_API_ID_VALUE && export KEY=YOUR_KEY_VALUE && node test.js
@pillamarip

This comment has been minimized.

Copy link

@pillamarip pillamarip commented Dec 16, 2020

Does this script need any changes? I get "message":"Request failed with status code 401","name":"Error","stack":"Error: Request failed with status code 401\n". Need some help

@mrpinghe

This comment has been minimized.

Copy link
Owner Author

@mrpinghe mrpinghe commented Dec 18, 2020

This still works as of yesterday.
A few things to check

  1. Is your ID and API key still valid?
  2. Did you generate a token for every request?
  3. Is your account authorized to call the API endpoint you are trying to access ?

If you are sure none of them is the issue, you probably need to post your code for me to help you

@pillamarip

This comment has been minimized.

Copy link

@pillamarip pillamarip commented Dec 18, 2020

Thank you for reaching back. It worked as is. Thank you!

@mrpinghe

This comment has been minimized.

Copy link
Owner Author

@mrpinghe mrpinghe commented Dec 18, 2020

Ah glad to see it worked out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment