[CryptoAPI] SHA encrypt and BASE64 encode

Forge Component
(19)
Published on 3 Mar by Ricardo Silva
19 votes
Published on 3 Mar by Ricardo Silva

I'm trying to recreate some java logic within outsystems using your module... this signs some data to be sent in an http post:


SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), HMAC_SHA256);
    Mac mac = Mac.getInstance(HMAC_SHA256);
    mac.init(secretKeySpec);
    byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8"));
    BASE64Encoder encoder = new BASE64Encoder();
    return encoder.encodeBuffer(rawHmac).replace("\n", "");


If this combination of methods correct from what you can see above?

Call ComputeMac with text to sign as my input and the signing secret key as Password

Call BinaryToBase64 on output ComputeMac.Mac


I'm coming up with a different string at the end of trying from Java vs Outsystems with a simple string like "harvey", I've tried a number of combos but can't make it match.


Thank you,
Charles



Solution

Passwords are not good keys, and that is why in CryptoAPI you have a PBKDF2 based method of deriving the key from a password.

That is the step that you're probably missing.

The specification for (some of) the algorithms used in CryptoAPI is in the documentation


In any case,  if you're looking for a Java implementation of CryptoAPI backend functions you can just pull if from my github. Should make your life easier.

Solution

Thank you very much for the rapid response, Ricardo, I'll have a look at the PBKDF2 and see if will resolve my issue. Just an FYI, I currently have the following working in an extension and get back the same results as from my Java...


public void MssEncrpytHmacSha256AndToBase64(string ssSecretKey, string ssTextToEncrypt, out string ssEncryptedText) {
            ssEncryptedText = "";
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            byte[] keyByte = encoding.GetBytes(ssSecretKey);
            HMACSHA256 hmacsha256 = new HMACSHA256(keyByte);
            byte[] messageBytes = encoding.GetBytes(ssTextToEncrypt);
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            ssEncryptedText = Convert.ToBase64String(hashmessage);
        }

Never use passwords as keys. Keys require high entropy which passwords do not have.

If you want to encrypt something using a password, you should always derive a key from it using standard and known to be secure methods for that, for example using PBKDF2.

Ricardo Silva wrote:

Never use passwords as keys. Keys require high entropy which passwords do not have.

If you want to encrypt something using a password, you should always derive a key from it using standard and known to be secure methods for that, for example using PBKDF2.

Ricardo, I am using a signing key that the vendor game to me so I have to sign with that; I have no choice. We have a separate "password" token that we pass in the form itself.


Thanks,
Charles