Hi everyoe,
I'm trying to connect with a webService, and I must encode a part of the header with SHA1 encoding. I have an example in .NET, and I'm trying to convert it into C/AL, but I'm receiving an error from the webService. The code in .NET is this:
byte[] key = Encoding.UTF8.GetBytes(secret);
byte[] hmac_encode = Sha1Hash_Raw(concat, key);
string hmac_encode_base64 = System.Convert.ToBase64String(hmac_encode);
private static byte[] Sha1Hash_Raw(string input, byte[] key)
{
HMACSHA1 sha1 = new HMACSHA1(key);
byte[] byteArray = Encoding.UTF8.GetBytes(input);
MemoryStream stream = new MemoryStream(byteArray);
return sha1.ComputeHash(stream);
}
The value I must include into the header of the HTTP request is "hmac_encode_base64"
This is how I'm trying to generate the hash in NAV:
key := Encoding.UTF8.GetBytes(secret);
hmacSHA1 := hmacSHA1.Create;
hmacSHA1.Key := key;
hmac_encode := hmacSHA1.ComputeHash(Encoding.UTF8.GetBytes(concat));
hmac_encode_base64 := Convert.ToBase64String(hmac_encode);
This are the variables:
secret Text
key DotNet System.Array.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
hmac_encode_base64 Text
hmacSHA1 DotNet System.Security.Cryptography.HMACSHA1.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
concat Text
hmac_encode DotNet System.Array.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Afer this try, I realizes that "ComputeHash" method in C# was receiving a MemoryStream. So I change my code to this:
key := Encoding.UTF8.GetBytes(secret);
hmacSHA1 := hmacSHA1.Create;
hmacSHA1.Key := key;
ConcatByte := Encoding.UTF8.GetBytes(concat);
Instr.READ(ConcatByte);
COPYSTREAM(MemoryStream,Instr);
hmac_encode := hmacSHA1.ComputeHash(MemoryStream);
hmac_encode_base64 := Convert.ToBase64String(hmac_encode);
But I'm havieng a "DotNEt type is not compatible" error in the "Instr.READ(ConcatByte);" sentence.
Any hint please?
Answers
Look for functions GenerateHash/GenerateKeyedHash in codeunit 1266 Encryption Management, I found them useful.
Note that GenerateKeyedHash works fine when generating just one hash from secret key.
If you need to loop the hash generation (e.g. as required by AWS), the Bytes value must not be converted to String between the steps.
To handle this I ended up writing my own function:
First of all, thnaks for your answer jurica.
I've read that this was easier as you said in BC365, but I didn't understand well. I've copied from the 1266 CU to my CU the methods GenerateKeyedHashBytes and TryGenerateKeyedHash, and I changed my code in this way:
But I get the same value in "hmac_encode_base64". Am I loosing something? Our somethin that I'm using wrong?
THnak you very much again, really appreciate your help
You can use the codeunit 1266 from NAV2018, there is this function that return the base64 already, you could need the table 1805
Regards
Muchas gracias!
I've used the function you hace told me, but aniway, the result it's being the same. I'm starting to think that the problem is in other field of the request header, but that is not the answer I'm receiveing from the aplication support...
Well this function return the base64 code from the passed text after the encryption.
What's "the result being the same" that you said ?
Regards.
As you can see in my frist message, I have an example in C# that I must translate it into C A/L.
My first try was this:
And after the discover of the 1266 Cu in BC, I'eve done this:
And weith the function you've shown me:
In all the cases, I ahve the same value into hmac_encode_base64 , but they are etlling me that it is incorrect...
Then I think that should be other issue in the call to the web service, because the last function that you are using give back the encrypted value
You can run this example in Python
And do the same in NAV and you get the same result.
It's not in base64 but does not matter.
Regards
That is what I think, ansd I'm trying to find or demostrate that the error is in another variable....
Thank you anyway, really appreciate.
Gracias!!
I'm still having problems, so I will try to start from the beginnig, checking the different steps. My first goal is to get the MD5 hash of a string.
In C# is this part of the code:
And I'm trying to convert into CA/L like this:
variables:
JsonString BigText
Hash DotNet System.Array.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
md5_base64 Text
MD5 DotNet System.Security.Cryptography.MD5.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
From support they are giving me a valuea for md5_base64 different to the one I'm getting...
Am I loosing something?
Thank you very much