【问题标题】:Delphi 10.2 Coinbase Pro API SignatureDelphi 10.2 Coinbase Pro API 签名
【发布时间】:2020-09-05 20:13:02
【问题描述】:

我正在尝试使用 Delphi 10.2 将 Coinbase Pro API 集成到我的程序中。

Coinbase Pro API 需要四个不同的标头,其中之一是经过加密的签名。我在形成有效签名时遇到问题。根据 Coinbase Pro API 文档:

CB-ACCESS-SIGN 标头是通过在 prehash 字符串时间戳 + 方法 + requestPath + 正文(其中 + 表示字符串连接)上使用 base64 解码的密钥创建 sha256 HMAC 和 base64 编码输出来生成的。时间戳值与 CB-ACCESS-TIMESTAMP 标头相同。body 是请求正文字符串,如果没有请求正文(通常用于 GET 请求)则省略。方法应为大写。

我知道时间戳是正确的,因为我首先从 coinbase 服务器获取它,然后将它传递给签名。所以我猜它与base64解码/编码或sha256 hmac有关。

我的签名功能是:

function Signature(RequestPath, TimeStamp, Method : String) : ANSIString;
var
  skeydecode : AnsiString;
  sha256     : AnsiString;
  prehash    : AnsiString;
  Body       : String;

begin
  Body := '';

  prehash    :=  TimeStamp + Method + RequestPath + Body ;

////Option 1 - [Coinbase] Invalid Signature
  skeydecode := TIdDecoderMIME.DecodeString(APISecret);
  sha256     := trim(CalculateHMACSHA256(prehash ,skeydecode));

  result     := Tidencodermime.EncodeString(sha256);

end;

然后我尝试使用的 HMAC 函数是:

function CalculateHMACSHA256(const value, salt: String): String;
var
  hmac: TIdHMACSHA256;
  hash: TIdBytes;
begin
  LoadOpenSSLLibrary;
  if not TIdHashSHA256.IsAvailable then
    raise Exception.Create('SHA256 hashing is not available!');
  hmac := TIdHMACSHA256.Create;
  try
    hmac.Key := IndyTextEncoding_UTF8.GetBytes(salt);
    hash := hmac.HashValue(IndyTextEncoding_UTF8.GetBytes(value));
    Result := ToHex(hash);
  finally
    hmac.Free;
  end;
end;

我通过 REST 请求成功连接到 Coinbase API,因为我能够连接到时间端点,但这不需要签名标头。

当尝试在其他 REST 请求中包含签名标头时,coinbase api 返回 Invalid Signature。

【问题讨论】:

  • 欢迎来到 StackOverflow。您需要编辑您的 q 以明确您正在寻求帮助的确切内容,即说明您的问题的症状是什么,如果您收到任何错误消息怎么办,等等。

标签: delphi encryption delphi-xe2 coinbase-api


【解决方案1】:

不要将AnsiString 用于二进制数据。您的数据正在通过 AnsiUnicode 转换。

将 base64 密钥解码为字节并将它们按原样用于 hmac 密钥,然后按原样对结果字节进行 base64 编码,而不是字节的十六进制编码表示。

试试这个:

function CalculateHMACSHA256(const value: String; const salt: TIdBytes): TIdBytes;
var
  hmac: TIdHMACSHA256;
begin
  LoadOpenSSLLibrary;
  if not TIdHashSHA256.IsAvailable then
    raise Exception.Create('SHA256 hashing is not available!');
  hmac := TIdHMACSHA256.Create;
  try
    hmac.Key := salt;
    Result := hmac.HashValue(IndyTextEncoding_UTF8.GetBytes(value));
  finally
    hmac.Free;
  end;
end;

function Signature(const RequestPath, TimeStamp, Method : String) : String;
var
  key : TIdBytes;
  sha256 : TIdBytes;
  prehash : String;
  Body : String;
begin
  Body := '';
  prehash := TimeStamp + UpperCase(Method) + RequestPath + Body;
  key := TIdDecoderMIME.DecodeBytes(APISecret);
  sha256 := CalculateHMACSHA256(prehash, key);
  Result := TIdEncoderMIME.EncodeBytes(sha256);
end;

【讨论】:

    猜你喜欢
    • 2020-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 2019-01-12
    • 2015-04-21
    • 1970-01-01
    相关资源
    最近更新 更多