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:
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)
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.
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
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
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, ¤tDateTime, &Nonce, &DataToSign, &Authorization;
Local object &oByteStr, &signingKey, &Hmac, &Hmacbytes, &oEncoder;
/* static values */
&companyCode = "ABC";
&clientKey = "My_ABC_keyname";
&secretKey = "6Ftp123345AbCdEfgH";
&resourcePath = "/sync/v2/profile";
¤tDateTime = 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) | ¤tDateTime;
&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);
No comments:
Post a Comment