xquerymarklogichmacsha256

Generate AWS Signature in MarkLogic XQuery - can't reproduce example hash


I need to send a GET request to AWS from MarkLogic and sign the URL. I was using the AWS documentation to understand how the signature gets created but what I get and what I expect to get aren't the same.

Sample data is from this page.

let $canonicalRequest :=
'GET
/test.txt
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
host:examplebucket.s3.amazonaws.com

host
UNSIGNED-PAYLOAD'

(: the value of this is correct, this is the same as the example, 3bfa292879f6447bbcda7001decf97f4a54dc650c8942174ae0a9121cf58ad04 :)
let $canonicalRequestHash := xdmp:sha256($canonicalRequest) 

let $stringToSign :=
'AWS4-HMAC-SHA256
20130524T000000Z
20130524/us-east-1/s3/aws4_request
' ||
$canonicalRequestHash

let $signingKey := xdmp:hmac-sha256(xdmp:hmac-sha256(xdmp:hmac-sha256(xdmp:hmac-sha256("AWS4wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY","20130524"),"us-east-1"),"s3"),"aws4_request")

return xdmp:hmac-sha256($signingKey,$stringToSign)

I get

ec43271c228d0d408e25dd8ec1e3b71ed7c1dbfe5c76bd7f272d3bff665e1f16

I would like to get

aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404


Solution

  • The secretKey parameter should be a binary node for the region, service, and signing keys. This should work:

    xquery version "1.0-ml";
    
    let $canonicalRequest :=
    'GET
    /test.txt
    X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
    host:examplebucket.s3.amazonaws.com
    
    host
    UNSIGNED-PAYLOAD'
    
    (: the value of this is correct, this is the same as the example, 3bfa292879f6447bbcda7001decf97f4a54dc650c8942174ae0a9121cf58ad04 :)
    let $canonicalRequestHash := xdmp:sha256($canonicalRequest) 
    
    let $stringToSign :=
    'AWS4-HMAC-SHA256
    20130524T000000Z
    20130524/us-east-1/s3/aws4_request
    ' ||
    $canonicalRequestHash
    
    let $dateKey := xdmp:hmac-sha256("AWS4wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "20130524")
    let $regionKey := xdmp:hmac-sha256(binary { xs:hexBinary($dateKey) }, "us-east-1")
    let $serviceKey := xdmp:hmac-sha256(binary { xs:hexBinary($regionKey) }, "s3")
    let $signingKey := xdmp:hmac-sha256(binary { xs:hexBinary($serviceKey) }, "aws4_request")
    
    return xdmp:hmac-sha256(binary { xs:hexBinary($signingKey) }, $stringToSign)