The CreatorCon Call for Content is officially open! Get started here.

SHA256 encode data with key

Travis_C
Giga Contributor

I have an API I'm attempting to call from ServiceNow, but I am running into issues with the SHA256 encoded data. In the request to the API, the Authentication header contains SHA256 encoded that is then converted to base64. The API documentation has an example for Node.js of how to get this to work, but it uses Crypto-JS. Crypto-JS is not included in ServiceNow and I could add it in if needed, but I would prefer to use to use something else that is already built into ServiceNow. 

 

Node.js

var crypto = require("crypto");
var hex = crypto.createHmac("sha256", apiKey).update(data).digest("hex");
var signature = new Buffer(hex).toString('base64');

python

signature = base64.b64encode(hmac.new(apiKey.encode(),msg=data.encode(),digestmod=hashlib.sha256).hexdigest().encode())

Is there a way to SHA256 encode a message with a specific key and then base64 encode the output in ServiceNow? Or do I need to add Crypto-JS to ServiceNow?

1 ACCEPTED SOLUTION

Travis_C
Giga Contributor

Just a follow up on this. I was able to get this working by:

  • Created a new app for CryptoJS to be created in. This was required to get it working due to scoping.
  • Created script include for CryptoJS using the instructions provided in the video Crypto-JS into ServiceNow
  • Created a system property to store the apiKey in as a password.

At this point, you can call the function HmacSHA256 from the script include CryptoJS in the application NodeJS with an application scope of x_fise_nodejs. Example below:

  • var sig = (x_fise_nodejs.CryptoJS.HmacSHA256(requestVars, apiKey));

My specific use case also required base64 encoding, which can be completed with by using GlideStringUil.base64Encode. Example below:

  • var signature = GlideStringUtil.base64Encode(sig);

With this complete, signature and some other information was stored in a variable authSig input into an HTTP Auth header and using a RestMessage to send the API. RestMessagev2 documentation is here.

View solution in original post

16 REPLIES 16

josh_nerius
ServiceNow Employee
ServiceNow Employee

Hi Travis, 

Check out these APIs: 

- CertificateEncryption

- GlideDigest

Travis_C
Giga Contributor

 

Josh,

Thank you for the quick reply. I ran through some testing and found that GlideCertificateEncryption doesn't work in testing. I can only test GlideCertificateEncryption by sending the request to the API server due to the output being [object CertificateEncryption]. The base64 encoded version does provide an output that is different than the Node.js output.

ServiceNow

var apiKey = "abc123"
var data = "something"
var mac = new GlideCertificateEncryption; 
apiKey = GlideSystem.base64Encode(apiKey);
mac.generateMac(apiKey, "HmacSHA256", data);
gs.info(mac)
var digest = new GlideDigest();
gs.info(digest.getMD5Base64(mac));
gs.info(GlideStringUtil.base64Encode(mac));

Output:
*** Script: [object CertificateEncryption] //GlideCertificateEncryption
*** Script: Uuf2IJQewynIObb1ufoE3A== //digest.getMD5Base64()
*** Script: W29iamVjdCBDZXJ0aWZpY2F0ZUVuY3J5cHRpb25d // GlideStringUtil.base64Encode()
Node.js
var apiKey = "abc123"
var data = "something"
var crypto = require("crypto");
var hex = crypto.createHmac("sha256", apiKey).update(data).digest("hex");
var signature = new Buffer(hex).toString('base64');
console.log(signature)

Output: 

YjRiNDRhNDY2NjU5NjNlM2M4NzE4NjI4YmMyNzk1ZDY0NDEzNjJmZGMyZjEwYTI0NzU0MTQ0Mjg5NTliY2MxOA==

I tested the output of GlideStringUtil.base64Encode() and digest.getMD5Base64(mac) in ServiceNow with a random string. GlideStringUtil.base64Encode() provides the same output as the Node.js Buffer(hex).toString('base64'). I'll continue to use GlideStringUtil.base64Encode() for my script.

Also, if I use CertificateEncryption, it errors with 'Evaluator: org.mozilla.javascript.EcmaError: "CertificateEncryption" is not defined.'. Using GlideCertificateEncryption, it provides an output of [object CertificateEncryption], but I cannot confirm that the output is the same as what Node.js provides using crypto.createHmac.

Also, thank you for your CreatorCon San Diego 2017 video. It has been very helpful to understand the full process to get Crypto-JS into ServiceNow.

Where you able to find a solution for this?I have the same requirement for HTTP Authorization header.

Travis_C
Giga Contributor

Just updated this with what I did to get it working. Let me know if you have any questions.