AWS Signature 4 SHA256 Key Hashing

Hi All,

I've been trying to sign an AWS Signature 4 http request using both the Java Cryptography Library plugin and the Cryptography tools plugin.  The Appian code near the bottom is using the latter, but I've been getting the same results using the macsignature function from the Java library.

AWS has sample data to validate the process here: https://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html

The pertinent part is..

key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'

kSecret = '41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559'  which is Hexencode("AWS4" + key)

kDate = '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d'

kRegion = '69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c'

kService = 'f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa'

kSigning = 'f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d'

Your program should generate the following values for the values in getSignatureKey. Note that these are hex-encoded representations of the binary data; the key itself and the intermediate values should be in binary format.

Using the below code I get the right result for kDate, but nothing is right after that. I'm assuming the reason is that I'm getting hex string back and I need to input a binary value, but I've tried encoding the subsequent keys to base64, but I still don't get the right values. To be honest I've tried just about everything I can think of in terms of hex-text binary encoding of the keys and values and I can't get the right values.  I was able to solve this with a SQL Server Function before, but that isn't an option now. Can anybody help determine if A) this is possible with Appian's Collating and Charater Encoding and B) If so how?

Please and thank you SO much for any guidance!

load(
local!key: "AWS4wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
local!date: "20120215",
local!region: "us-east-1",
local!service: "iam",
local!request: "aws4_request",
local!kdate: hmacsha256hash(local!key, local!date),
local!kRegion: hmacsha256hash(local!kdate, local!region),
local!kService: hmacsha256hash(local!kRegion, local!service),
local!signing: hmacsha256hash(local!kService, local!request),
local!signing
)

 

 

-JJ

  Discussion posts and replies are publicly visible

  • 0
    Appian Employee
    in reply to Josh

    ah, my apologies. I've edited my previous comment so as to not confuse any future viewers. The review process should be pretty quick, especially for something developed in-house, but I'll double check to see where things are at. 

  • 0
    Appian Employee
    in reply to Josh

    The review is complete, but it might take a day or two for it to be available. So I think it should show up for you at some point on Monday. If you have cloud sites, you'll be able to add it through the Admin Console. Otherwise, you'll be able to download it through the App Market, and then follow the normal instructions to install a plugin. 

    Also, I saw your comment on the plugin's app market page asking about the secure credentials store. That's good thinking, so I'm adding that capability to the plugin (just for the AWS signature function, for now, rather than for all the functions.) So, you'll actually want version 2.1.0 .

  • +1
    Appian Employee
    in reply to Josh

    Alright, so, final update for now: the 2.0.0 version, with the getSignatureKey method, should be available within 24 hours or so for download from the App Market, and/or installation to Cloud Sites through the Admin Console.

    The 2.1.0 release, which has support for the secure credentials store, will likely be available at some point on Monday or Tuesday.

    Once the plugin is installed, the function tooltip (the function will be "getSignatureKey", under the cryptography functions category) should answer most questions, but if any questions or concerns do come up, just let me know. , fyi as well.  

  • Eliot,

    Thank you so much!  I'm using v2.0 of the plugin and the getSignatureKey function appears to work as expected. There is a slight challenge though.  After numerous attempts, I was unable to produce a signature that matched AWS samples.  After doing some more research, it appears the "string to sign" must be signed using the byte array of the signature key, not the hex string.  Here's an example I found (look at the calculateSignature method)https://www.javaquery.com/2016/01/aws-version-4-signing-process-complete.html

    Would you have time to update the plugin with that additional piece?

  • 0
    Appian Employee
    in reply to Josh

    Is there any point in the process where we get a result that isn't a byte array? For example, once the string is signed, is it a string, or a byte array? 

    Basically, the challenge is that we do technically have a "binary" type in Appian, but it's rather old, and we don't have a type converter for it (which is why you can't, for example, use it as the type for a rule input.) Adding support for that would require me to make a change at the product level, which would be a much more involved effort. 

    So, the goal is to do all the byte operations in the plugin, and then return some other type back, like a string. 

    With that in mind, do you think it would work for you if the method had you additionally pass the text you want to sign, signed it with the hmacsha256hash function, and then returned the signed text (in... hex encoded form, I guess?)? Or does the signed text also need to remain in binary?

  • In all honesty, I was a bit impatient and wasn't sure if you would have time to make other changes, so I created my own plugin which basically does as you've described.  I modified the getSignatureKey to be a private method that returns the byte array and then added a new method for creating the signature, returning it as a hex encoded string.  I also added the use of secure credential store.  I'm still waiting for it to be deployed in our dev environment so I can test it fully. Once I've tested it, I'd be happy to share the source code so you can implement it in the Cryptography  Hash Functions plugin.

  • 0
    Appian Employee
    in reply to Josh

    That's great! One of the reasons we like to include the source code in our plugins is so that people can learn from them and build off them. I'm glad to hear you were able to do just that. 

  • We are working on an integration with Buckaroo, Buckaroo needs a secret key in the header.

    The key also need a hash on byte level, we are almost there in creating the expression but there is one problem.

    The functionality that is missing is in the current crypto plugin is the hmcasha256 hash on byte level instead of string level.

     

    Buckaroo documentation: https://dev.buckaroo.nl/Apis/Description/json#codeexampleincsharp

    example code C# line 63: 

    var secretKeyByteArray = Encoding.UTF8.GetBytes(SecretKey)

     

    Can you help us or give us pointers regarding the hash?

  • Are you looking for a method that will take in a byte array (as the key) and a string (the value to sign), and return a hex string (using the byte array to sign the string)? Or are you also needing to generate the key itself? 

    , I'm trying to figure out if this is the same problem you were having. Can you tell? It seems like one possible solution (if I can do it) would be to 1) give a snippet of SAIL that would take a hex string and convert it to binary 2) add a hmacsha256(bytes, string) method that you could then pass that binary string to. Does that sound right?