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

itstk
Tera Contributor
Hello everyone,
Could someone help me convert this code from python to background script.

I did a conversion but it doesn't work for me, I get different values ​​as a response.

Python Script

import hmac
import hashlib
import json

from urllib.parse import unquote

API_SECRET = '!nh+7g0)@em!+meef%vjdp83d!c+s#g_r5_8oy&85=j52min=c'
api_key_bytes= bytes(API_SECRET, 'utf-8')
data = {
"username":"admin",
"password":"12345678"
}

data_str = json.dumps(data, ensure_ascii=False)
print('data_str: ', data_str)
signature = hmac.new(api_key_bytes,msg=data_str.encode('utf-8'),digestmod=hashlib.sha256).hexdigest().upper()

# se utiliza para peticiones POST y PUT
print(f'Data - {signature}')

 

Response Python:
91CBC3E326CF2871FE782ACAB33A9E48411AF702D835E4A2015175DD05338C85

 

Servicenow Script

var API_SECRET = '!nh+7g0)@em!+meef%vjdp83d!c+s#g_r5_8oy&85=j52min=c';
var api_key_bytes= String(Key, 'utf-8');
gs.print(api_key_bytes);
var data = {"username": "admin", "password": "12345678"};
data=JSON.stringify(data);
data=String(data, 'utf-8')
gs.print(data);
var mac = new GlideCertificateEncryption;
signature = mac.generateMac(Key,"HmacSHA256",data);
var digest = new GlideDigest();
var hex = digest.getSHA256Hex(signature);
gs.print(hex);

Response Servicenow:

5A30F7AB94EAD70206D2953EF921B511BC1C990CFD86A25E26CA18A6083755E1


Someone who can help me convert the code or how I can do something similar.

Thank you
 
 

Hi Itsk,

 

I had a similar problem, see my solution and answer here:

https://community.servicenow.com/community?id=community_question&sys_id=62ad6332dbcf0810d58ea345ca96...

Hope it helps.