简体   繁体   中英

Generating OVH SHA1 signature

I'm trying to utilize the OVH API in Delphi using the REST client. For this OVH requires me to generate a signature, but their documentation does not provide much info on this other than:

"$1$" + SHA1_HEX(AS+"+"+CK+"+"+METHOD+"+"+QUERY+"+"+BODY+"+"+TSTAMP)

They do provide thin wrappers for other languages so I thought I could take a look at those and try to replicate it. I found the following for generating the signature in C# and have extracted the function to be used in a test application.

Test app C# code:

textBox1.Text = GenerateSignature("appSecret", "consKey", 123456789, "PUT", "/path/to/api", "TEST DATA");

The C# result is:

$1$8336ecc5d03640b976e0b3ba005234a3046ab695

I attempted the rewrite the function in Delphi and came up with the following function:

function GenerateSignature(const appSecret, consKey: string;
  const currentTimeStamp: LongInt; const method, target: string;
  const data: string = ''): string;
begin
  var
  toSign := string.Join('+', [appSecret, consKey, method, target, data,
    currentTimeStamp]);

  var
  binaryHash := THashSHA1.GetHashBytes(toSign);

  var
  signature := '';
  for var byte in binaryHash do
  begin
    signature := signature + byte.ToHexString.ToLower;
  end;

  Result := '$1$' + signature;
end;

And to test it:

procedure Main;
const
  APP_SECRET = 'appSecret';
  CONSUMER_KEY = 'consKey';
  method = 'PUT';
  target = '/path/to/api';
  data = 'TEST DATA';
  CURRENT_TIMESTAMP = 123456789;
begin
  Writeln(GenerateSignature(APP_SECRET, CONSUMER_KEY, CURRENT_TIMESTAMP,
    method, data));
end;

Both test applications in C# and in Delphi use the same data but produce different outputs. My expected output is:

$1$8336ecc5d03640b976e0b3ba005234a3046ab695

But I end up getting the following output from delphi:

$1$d99fd5086853e388056d6fe37a9e2d0723de151b

I do not know C# very well but it seems to get the hashbytes then convert it to hex and stitch it together. How can I modify the Delphi function I wrote so that I can get my expected result?

Thanks to the last parameter being optional you didn't notice (because no compiler error/warning) that you actually missed one parameter when calling/testing your function, resulting in a text of 'appSecret+consKey+PUT+TEST DATA++123456789' to be hashed. Which is indeed

d99fd5086853e388056d6fe37a9e2d0723de151b

Let me reformat your test to make it more obvious:

const
  APP_SECRET = 'appSecret';
  CONSUMER_KEY = 'consKey';
  CURRENT_TIMESTAMP = 123456789;
  method = 'PUT';
  target = '/path/to/api';  // Where is this used?
  data = 'TEST DATA';
begin
  GenerateSignature
  ( APP_SECRET
  , CONSUMER_KEY
  , CURRENT_TIMESTAMP
  , method
  // Forgotten parameter
  , data  // becomes "target"
  );
end;

Consider making const data: string = '' mandatory, too, instead of optional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM