function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Frank van Meegen 35Frank van Meegen 35 

Generate hmac SHA256 with apex

Hi all,

For authorization to an endpoint I need a signature based on the HMAC SHA256 encryption. This signature should be created from a query string and a secret key.

I use the following code in apex to create the signature. The problem is that it returns a signature with 44 characters including non alphanumeric characters where I would expect a signature with 64 alphanumeric characters. If I use any of the online HMAC SHA256 converters I get a valid signature with 64 alphanumeric characters.

How can I modify the apex code so I will receive a signature with 64 alphanumeric characters that is complient to '^[A-Fa-f0-9]{64}$'
 
public class generateHmac {

        public static void generateSignature() {
                    DateTime dateTimeNow = dateTime.now();
        String unixTime = ''+dateTimeNow.getTime()/1000;
    string url = 'timestamp=' + unixTime;

string privateKey = 'PRIVATEKEY';


Blob privateKeyBlob = EncodingUtil.base64Decode(privateKey);
//Blob privateKeyBlob = Blob.valueOf(privateKey);
Blob urlBlob = Blob.valueOf(url);
Blob signatureBlob = Crypto.generateMac('HmacSHA256', urlBlob, privateKeyBlob);

String signature =EncodingUtil.base64Encode(signatureBlob);
            
system.debug('signature is ' +signature);

        } 
}

 
Kushal MishraKushal Mishra
Hi All,

I am getting the issue, getting 44 characters only but the result should be 64 characters, Please help me its bit urgent.
Yad Jayanth 4Yad Jayanth 4
when you encode the blob to get your signature, try using EncodingUtil.convertToHex(signatureBlob) instead of base64Encode
Seemu Saikia 6Seemu Saikia 6
Here is the code to encrypt a string to SHA256 hash format : 

//value to process
Blob data= Blob.valueOf('Any String');

or in case of field value

Blob data= Blob.valueOf(sObject.FieldAPIName));

Blob hash = Crypto.generateDigest('SHA-256', data);

//Convert SHA-256 Hash data to String
String encryptedString =EncodingUtil.convertToHex(hash);

Thanks 
 
Ankush SomaniAnkush Somani
Please use below code to verify incoming HTTP POST REQUEST 
 
string secret= 'a5db7f9cb87859b703b0e30a5f130d2b'; //Hex Key which we already have 
//RestRequest request = RestContext.request;
//String signature = request.headers.get('Content-Hmac'); this might change in each integration like 'X-Signature'
String signature = 'acf36fa939dbbb8e05e94814574caaf64ca73cae0701ba435f1ee0768830ca8c';  //Received in HTTP Request
Blob hmac = Crypto.generateMac('HMACSHA256', blob.valueOf('ABCD'), EncodingUtil.base64Decode(secret)); 
String matchWithSignature =  EncodingUtil.convertToHex(hmac));
//matchWithSignature ==signature
Manish SwamyManish Swamy

I am getting Invalid credentials error.

Have you solved signature creation problem? maybe I am getting error because signature is not getting created properly

Manish SwamyManish Swamy
This is in JavaScript 
Can someone help me to convert it into APEX

const timeStamp = Math.floor(Date.now());
const key = "";
const secret = ""
const body = { "timestamp": timeStamp }
const payload = new Buffer(JSON.stringify(body)).toString();
const signature = crypto.createHmac('sha256', secret).update(payload).digest('hex')
const options = {
url: baseurl + "/exchange/v1/users/balances",
headers: { 'X-AUTH-APIKEY': key, 'X-AUTH-SIGNATURE': signature },
json: true,
body: body
}
request.post(options, function(error, response, body) { console.log(body); })