Showing posts with label HMAC. Show all posts
Showing posts with label HMAC. Show all posts

Saturday, December 20, 2025

Generating HMAC SHA512 Digest for REST API

Recently a request came my way to use a 3rd party API which uses HMAC (Hash-Based Message Authentication Code) to secure requests.

Key Components of HMAC Authentication
1. Secret Key ( Secret_Key ): A confidential key 

2. API Key ( Api_Key ): A unique identifier assigned to the client, typically representing the user or system accessing the API.

3. Nonce ( Nonce ): A unique, single-use number is generated for each request.

Generating an HMAC Signature
To authenticate an API request:

1. Concatenate the Following Elements (each separated by a newline \n ):

        HTTP Method (e.g. PUT,POST,GET,DELETE)
        Resource Path (e.g. sync/v2/profile)
        API Key (e.g. user)
        Nonce (e.g. 123456)
        Date (RFC 1123 format, e.g. Sat, 20 Dec 2025 12:00:00 GMT)

2. Generate the HMAC Digest:

Use the Secret Key with the HMAC-SHA512 algorithm to hash the concatenated string.
Encode the hashed output in Base64.

3. Format the Authorization Header:

Authorization: HmacSHA512 Api_Key:Company_Code:Nonce:Digest

Example Request
Secret Key: my_secret_key
API Key: user
Company Code: STK
Nonce: 123456
Date: Sat, 20 Dec 2025 12:00:00 GMT

Authorization Header Example
Authorization: HmacSHA512 user:STK:123456:px4KjfYAg6RY56sZ93nPSP8aiZqoIPp4DKTIIZKkzZwEAb

PeopleSoft does not provide SHA512 algorithm API calls to handle this natively hence have to use delivered java libraries leveraging the CreateJavaObject peoplecode API.


Local string &companyCode, &clientKey, &secretKey, &resourcePath, &currentDateTime, &Nonce, &DataToSign, &Authorization;
Local object &oByteStr, &signingKey, &Hmac, &Hmacbytes, &oEncoder;

/* static values */
&companyCode = "ABC";
&clientKey = "My_ABC_keyname";
&secretKey = "6Ftp123345AbCdEfgH";
&resourcePath = "/sync/v2/profile";
&currentDateTime = DateTimeToHTTP(%Datetime);
&Nonce = String(Int(Rand() * 1000000));

/* Generate the HMAC Digest */
&oByteStr = CreateJavaObject("java.lang.String", &secretKey);
&signingKey = CreateJavaObject("javax.crypto.spec.SecretKeySpec", &oByteStr.getBytes("UTF8"), "HmacSHA512");
&Hmac = GetJavaClass("javax.crypto.Mac").getInstance("HmacSHA512");
&Hmac.init(&signingKey);
&DataToSign = "GET" | Char(10) | &resourcePath | Char(10) | &clientKey | Char(10) | &Nonce | Char(10) | &currentDateTime;
&Hmacbytes = &Hmac.doFinal(CreateJavaObject("java.lang.String", &DataToSign).getBytes("UTF8"));
&oEncoder = CreateJavaObject("com.peoplesoft.tools.util.Base64");
&Authorization = &oEncoder.encode(&Hmacbytes);
&Authorization = "HmacSHA512 " | &clientKey | ":" | &companyCode | ":" | &Nonce | ":" | &Authorization;

Then send the authorization value in the header of the request, like so.

&bRet = &request.IBInfo.LoadRESTHeaders();
&bRet = &request.IBInfo.IBConnectorInfo.AddConnectorProperties("Authorization", &Authorization, %Header);