生成 OVH SHA1 签名

Generating OVH SHA1 signature

我正在尝试使用 REST 客户端在 Delphi 中使用 OVH API。为此,OVH 要求我生成一个 signature, but their documentation 除了以下内容外没有提供太多信息:

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

他们确实为其他语言提供了精简包装器,所以我想我可以看看那些并尝试复制它。我为 generating the signature in C# 找到了以下内容,并提取了要在测试应用程序中使用的函数。

测试应用 C# 代码:

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

C# 结果是:

36ecc5d03640b976e0b3ba005234a3046ab695

我尝试重写 Delphi 中的函数并提出以下函数:

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 := '$' + signature;
end;

并对其进行测试:

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;

C# 和 Delphi 中的测试应用程序使用相同的数据但产生不同的输出。我的预期输出是:

36ecc5d03640b976e0b3ba005234a3046ab695

但我最终从 delphi 得到以下输出:

$d99fd5086853e388056d6fe37a9e2d0723de151b

我不太了解 C#,但它似乎获取哈希字节然后将其转换为十六进制并将其拼接在一起。如何修改我编写的 Delphi 函数以获得预期结果?

由于最后一个参数是可选的,您没有注意到(因为没有编译器 error/warning)您在 calling/testing 函数时实际上错过了一个参数,导致文本为 'appSecret+consKey+PUT+TEST DATA++123456789' 进行哈希处理。这确实是

d99fd5086853e388056d6fe37a9e2d0723de151b

让我重新格式化您的测试以使其更明显:

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;

考虑将 const data: string = '' 设为强制性,而不是可选性。