bsw
bsw

Reputation: 153

Make AWS Signature Version 4 Request in Delphi 10.3 , porting Python code to Delphi

I am trying to build an AWS Signature Version 4 Request in Delphi.

I manage to handle the signing part but have some issue with the Canonical Request

I am following the link below to create a Canonical Request https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html

If I do it in Python3 see code below I get the correct answer f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59

I am trying to do the same in Delphi

The result is WRONG code bfc216a33de74e30285fc72d6dd2035508e9aec861e5d56b59f4c1eb4f29ddc3

Anyone now howto do this Python line below in Delphi

PYTHON
canonical_request_hash = hashlib.sha256((canonical_request).encode('utf-8')).hexdigest()

And get this result f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59

PYTHON CODE
canonical_request = "GET\n"+"/\n"+"Action=ListUsers&Version=2010-05-08\n"+"content-type:application/x-www-form-urlencoded; charset=utf-8\n"+"host:iam.amazonaws.com\n"+ "x-amz-date:20150830T123600Z\n"+ "\n"+ "content-type;host;x-amz-date\n"+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"


canonical_request_hash = hashlib.sha256((canonical_request).encode('utf-8')).hexdigest()

print(canonical_request_hash)
DELPHI
 canonical_request :=  'GET\n'+'/\n'+'Action=ListUsers&Version=2010-05-08\n';
 canonical_request := canonical_request +'content-type:application/x-www-form-urlencoded; charset=utf-8\n'+'host:iam.amazonaws.com\n'+ 'x-amz-date:20150830T123600Z\n"+ "\n"+ "content-type;host;x-amz-date\n'+ 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';

 canonical_request_hashed :=   BytesToHexConverter ( THashSHA2.GetHashBytes(UTF8Encode( canonical_request )));  // Struggle 

memo1.Lines.Add(canonical_request_hashed);
 memo1.Lines.Add('f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59');

//*********************

function TForm1.BytesToHexConverter(b: Tbytes): string;
var
 I        : Integer;
 s        : String;
begin
 s:='';
 for i  := 0 to length(b)-1 do
   begin
    s:=s+b[i].ToHexString;
   end;
 s:= LowerCase(s);
 result:=s;
End;

I expect this result in delphi f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59 but get this bfc216a33de74e30285fc72d6dd2035508e9aec861e5d56b59f4c1eb4f29ddc3

Upvotes: 1

Views: 634

Answers (1)

Peter Wolf
Peter Wolf

Reputation: 3830

Your'e trying to calculate SHA256 hash from the sample cannonical request that appears on AWS documentation page. As plain text it reads:

GET
/
Action=ListUsers&Version=2010-05-08
content-type:application/x-www-form-urlencoded; charset=utf-8
host:iam.amazonaws.com
x-amz-date:20150830T123600Z

content-type;host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

You've successfully converted this plain text to Python string, but you failed to do that in Delphi because of two reasons:

  1. You copy-pasted Python code to Delphi and replaced some " with ', but not all of them as the comment below the question points out.
  2. Delphi doesn't allow backslash escapes within string literals. You can only escape single quote ' by typing two single quotes ''. All other characters you either type directly or use # -prefixed character literals. So you should also convert all occurences of \n to #10 (new line character) and put it outside of string literal.

The correct translation to Delphi is:

canonical_request :=
  'GET'#10 +
  '/'#10 +
  'Action=ListUsers&Version=2010-05-08'#10 +
  'content-type:application/x-www-form-urlencoded; charset=utf-8'#10 +
  'host:iam.amazonaws.com'#10 +
  'x-amz-date:20150830T123600Z'#10 + 
  #10 +
  'content-type;host;x-amz-date'#10 +
  'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';

In the end it turns out that it's not a hexdigest() issue as written in the title, but rather an issue of porting Python code to Delphi.

Upvotes: 3

Related Questions