Forum Discussion

Mosh's avatar
Mosh
Icon for Professor rankProfessor
5 years ago

Using REST API from ServiceNow Scripting

I would like to use the REST API from ServiceNow but I'm not able to generate the HMAC using the ServiceNow Glide System native class GlideCertificateEncryption(), the resulting values don't match with what I would expect from Python or PowerShell.  Are there any ServiceNow developers out there who have managed to call the LogicMonitor REST API from a ServiceNow script? If you have, could anyone share an example script please.

var JavaString = Packages.java.lang.String;

var key = new JavaString("key"); 
var message = new JavaString("message"); 

var keyUTF8 = new JavaString(key.getBytes("UTF8"));
var messageUTF8 = new JavaString(message.getBytes("UTF8"));

var util = new GlideStringUtil();
var encryption = new GlideCertificateEncryption();

//var mac = encryption.generateMac(util.base64Encode(keyUTF8), "HMACSHA256", messageUTF8);    
var mac = encryption.generateMac(HexUtil.convertToBase64(keyUTF8 + ""), "HMACSHA256", messageUTF8 + "");    

gs.log(mac);
gs.log(HexUtil.convertToBase64(mac));

var decoded = util.base64Decode(mac);
var utf8Bytes = decoded.getBytes("UTF8");

gs.log(utf8Bytes.length);
gs.log(JSON.stringify(utf8Bytes));
 

  • Solved it. For anyone who needs it here is how to generate the MAC part of the signature using only native ServiceNow script and classes.  (I had to write my own convertByteArrayToHex() utility as there was nothing I could find native in ServiceNow.)  The problem with using CryptoJS is that in ServiceNow it would only be allowed in a scoped app and I wanted to do this in the global scope.

    var HexUtil = 
    {
      convertByteArrayToHex : function(byteArray)
      {
        var hex = "";
     
        byteArray.forEach(function(byteValue) { hex += HexUtil.convertByteToHex(byteValue); });
     
        return hex;  
      },
     
      convertByteToHex : function(b) 
      {
        var hexChar = ["0""1""2""3""4""5""6""7","8""9""a""b""c""d""e""f"];
      
        return hexChar[(b >> 4& 0x0f+ hexChar[b & 0x0f];
      }
    };
     
    var key = "key";
    key = encodeURIComponent(key);
    key = GlideStringUtil.base64Encode(key);
     
    var msg = "message";
    msg = encodeURIComponent(msg);
     
    var mac = new GlideCertificateEncryption();
    signature = mac.generateMac(key, "HmacSHA256", msg);
    gs.print(signature);
     
    // Yes! bp7ym3X//Ft6uuUn1Y/a2y/kLnIZARl2kXNDBl9Y7Uo=
     
    var bytes = GlideStringUtil.base64DecodeAsBytes(signature);
    gs.print(JSON.stringify(bytes));
    gs.print(bytes.length);
     
    var hex = HexUtil.convertByteArrayToHex(bytes);
    gs.print(hex);
     
    // Yes! 6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a
     
    var hexB64 = GlideStringUtil.base64Encode(hex);
    gs.print(hexB64);
     
    // Yes! NmU5ZWYyOWI3NWZmZmM1YjdhYmFlNTI3ZDU4ZmRhZGIyZmU0MmU3MjE5MDExOTc2OTE3MzQzMDY1ZjU4ZWQ0YQ==
  • When I lasted looked at it SN didn't have the built in hash function to implement the auth needed for LM. If you install the "LogicMonitor Incident Management Integration" add-on from the ServiceNow store, It provides some supporting script includes functions you may be able to use.

  • Solved it. For anyone who needs it here is how to generate the MAC part of the signature using only native ServiceNow script and classes.  (I had to write my own convertByteArrayToHex() utility as there was nothing I could find native in ServiceNow.)  The problem with using CryptoJS is that in ServiceNow it would only be allowed in a scoped app and I wanted to do this in the global scope.

    var HexUtil = 
    {
      convertByteArrayToHex : function(byteArray)
      {
        var hex = "";
     
        byteArray.forEach(function(byteValue) { hex += HexUtil.convertByteToHex(byteValue); });
     
        return hex;  
      },
     
      convertByteToHex : function(b) 
      {
        var hexChar = ["0""1""2""3""4""5""6""7","8""9""a""b""c""d""e""f"];
      
        return hexChar[(b >> 4& 0x0f+ hexChar[b & 0x0f];
      }
    };
     
    var key = "key";
    key = encodeURIComponent(key);
    key = GlideStringUtil.base64Encode(key);
     
    var msg = "message";
    msg = encodeURIComponent(msg);
     
    var mac = new GlideCertificateEncryption();
    signature = mac.generateMac(key, "HmacSHA256", msg);
    gs.print(signature);
     
    // Yes! bp7ym3X//Ft6uuUn1Y/a2y/kLnIZARl2kXNDBl9Y7Uo=
     
    var bytes = GlideStringUtil.base64DecodeAsBytes(signature);
    gs.print(JSON.stringify(bytes));
    gs.print(bytes.length);
     
    var hex = HexUtil.convertByteArrayToHex(bytes);
    gs.print(hex);
     
    // Yes! 6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a
     
    var hexB64 = GlideStringUtil.base64Encode(hex);
    gs.print(hexB64);
     
    // Yes! NmU5ZWYyOWI3NWZmZmM1YjdhYmFlNTI3ZDU4ZmRhZGIyZmU0MmU3MjE5MDExOTc2OTE3MzQzMDY1ZjU4ZWQ0YQ==
  • var hex = HexUtil.convertByteArrayToHex(bytes);
    gs.print(hex);
    hex is coming as empty please help
  • On 9/16/2020 at 7:13 AM, sirisha said:
    var hex = HexUtil.convertByteArrayToHex(bytes);
    gs.print(hex);
    hex is coming as empty please help

    Hi @sirisha,

    Can you paste more of your code?  Need to see what you are doing before you call this function.