gpt4 book ai didi

Delphi HMAC SHA512 签署了对 Bittrex 交易所的调用

转载 作者:行者123 更新时间:2023-12-03 15:36:22 28 4
gpt4 key购买 nike

我已经为此工作了一段时间,但我无法从服务器获得成功的响应。所有相关文档均可在 Bittrex Exchange Wesite 中找到。

签名位的主要症结可以在身份验证标题下找到

<小时/>我一直在使用的哈希文件可以在 Fundamentals 找到。在 SourceForge 上。它位于底部,称为 Fundamentals Hash 4.00.15

我一直使用这个文件的原因很简单,它似乎是唯一给我正确答案的文件。或者我应该说,与此 Hashing Website 的结果相比,它给了我正确的答案。正在给我。

我尝试使用 Indy 组件生成正确的哈希值,但它似乎与网站上的值不匹配。也许我没有正确使用它或正确的库或其他东西,但我也会添加我创建的示例。(当我写这篇文章时,我刚刚再次测试,看起来我确实得到了正确的答案,想想吧,也许我正在使用更好的 OpenSSL 库。无论如何,我也会把我的 INDY 示例放在下面)。


function Test: String;
const
FAPIKey = 'APIKEY';
FAPISecret = 'APISECRET';
FURL = 'https://bittrex.com/api/v1.1/account/getbalances?apikey=%s&nonce=%d';
var
FPost, FSignature: String;
FNonce: Integer;
Response: TStringStream;
HTTP: TIdHTTP;
SSL:TIdSSLIOHandlerSocketOpenSSL;
begin
Result := '';

FNonce := DateTimeToUnix(Now);
FPost := Format(FURL, [FAPIKey, FNonce]);

HTTP := TIdHTTP.Create;
try
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
try
HTTP.IOHandler := SSL;

FSignature := SHA512DigestToHex(CalcHMAC_SHA512(FAPISecret, FPost));
HTTP.Request.CustomHeaders.AddValue('apisign', FSignature);

Response := TStringStream.Create;
try
HTTP.Get(FPost, Response);
Result := Response.DataString;
finally
Response := nil;
end;
finally
SSL := nil;
end;
finally
HTTP := nil;
end;
end;

<小时/>在使用这个版本进行哈希之前,我只得到过'{“成功”:假,“消息”:“APISIGN_NOT_PROVIDED”,“结果”:空}'当我制定了自定义 HTTP header 后,我终于继续前进,现在得到了'{“成功”:假,“消息”:“INVALID_SIGNATURE”,“结果”:空}'它可能是一些简单的东西,例如无效的随机数,还是太旧的随机数?一切看起来都正常还是我缺少 INDY 组件的一些基本组件设置?

function Test: String;
const
FAPIKey = 'APIKEY';
FAPISecret = 'APISECRET';
FURL = 'https://bittrex.com/api/v1.1/account/getbalances?apikey=%s&nonce=%d';
var
FPost, FSignature: String;
FNonce: Integer;
Response: TStringStream;
HTTP: TIdHTTP;
SSL:TIdSSLIOHandlerSocketOpenSSL;
FSHA512Hasher: TIdHMACSHA512;
begin
Result := '';
if not LoadOpenSSLLibrary then exit;

FNonce := DateTimeToUnix(Now);
FPost := Format(FURL, [FAPIKey, FNonce]);

HTTP := TIdHTTP.Create;
try
SSL := TIdSSLIOHandlerSocketOpenSSL.Create(HTTP);
try
HTTP.IOHandler := SSL;

FSHA512Hasher := TIdHMACSHA512.Create;
try
FSHA512Hasher.Key := ToBytes(FAPISecret);
FSignature := Lowercase(ToHex(FSHA512Hasher.HashValue(ToBytes(FPost))));
finally
FSHA512Hasher := nil;
end;

HTTP.Request.CustomHeaders.AddValue('apisign', FSignature);

Response := TStringStream.Create;
try
HTTP.Get(FPost, Response);
Result := Response.DataString;
finally
Response := nil;
end;
finally
SSL := nil;
end;
finally
HTTP := nil;
end;
end;

最佳答案

我也遇到过类似的问题,但我最终解决了。我使用了通过 google 搜索找到的 hmac.pas 单元,但必须修改它才能与 10.1 Seattle 一起使用(特别是 IDBytes 有点不同)。

重要提示:我还必须修改 hmac.pas 单元以删除函数 HexStr 变体前面的“0x”。

另外:我将所有输入设置为 ansisstring。

我对此的测试函数如下。

function TBTXClient.Get(sCommand, sAddParams: string): string;
var
sURL: string;
nonce: string;
res: string;
sec2: string;
sha: TIDHashSha256;
hmac: TIdHMAC;
hash: string;
ms: TMemoryStream;
begin
nonce := inttostr(getticker);
sURL := 'https://bittrex.com/api/v1.1/'+sCommand+'?apikey='+MY_KEY+'&nonce='+nonce+sAddParams;

hash := THMACUtils<TIDHMacSha512>.HMAC_HexStr(MY_SECRET,sURL);

//Debug.Log('url = '+sUrl);
//Debug.Log('hash = '+hash);
QuickHTTPSGet(sURL, res, 'apisign', hash);

result := res;

end;

我的 hmac.pas 单元的修改版本(有一些新的依赖项)

unit hmac;

interface

uses
System.SysUtils,
EncdDecd,
IdHMAC,
IdSSLOpenSSL,
helpers.indy,
idglobal,
IdHash;

type
localstringtype = ansistring;

THMACUtils<T: TIdHMAC, constructor> = class
public
class function HMAC(aKey, aMessage: localstringtype): TIdBytes;
class function HMAC_HexStr(aKey, aMessage: localstringtype): localstringtype;
class function HMAC_Base64(aKey, aMessage: localstringtype): localstringtype;
end;

implementation

class function THMACUtils<T>.HMAC(aKey, aMessage: localstringtype): TIdBytes;
var
_HMAC: T;
begin
if not IdSSLOpenSSL.LoadOpenSSLLibrary then Exit;
_HMAC:= T.Create;
try
_HMAC.Key := AnsiStringToIDBytes(aKey);
Result:= _HMAC.HashValue(AnsiStringToIDBytes(aMessage));
finally
_HMAC.Free;
end;
end;

class function THMACUtils<T>.HMAC_HexStr(aKey, aMessage: localstringtype): localstringtype;
var
I: Byte;
begin
Result:= '';//'0x';
for I in HMAC(aKey, aMessage) do
Result:= Result + IntToHex(I, 2);
end;

class function THMACUtils<T>.HMAC_Base64(aKey, aMessage: localstringtype): localstringtype;
var
_HMAC: TIdBytes;
begin
_HMAC:= HMAC(aKey, aMessage);
Result:= EncodeBase64(_HMAC, Length(_HMAC));
end;

end.

您可能还需要这个辅助单元。

unit helpers.indy;

interface

uses
idglobal, types, classes, sysutils, typex;


function TBytesToIDBytes(b: TBytes): TIDBytes;
function AnsiStringToIDBytes(a: ansistring): TIDBytes;

implementation


function TBytesToIDBytes(b: TBytes): TIDBytes;
var
t: ni;
begin
setlength(result, length(b));
for t := low(b) to high(b) do
result[t] := b[t];

end;
function AnsiStringToIDBytes(a: ansistring): TIDBytes;
var
t: ni;
begin
setlength(result, length(a));
for t := 0 to length(a)-1 do
result[t] := ord(a[STRZ+t]);

end;

这个俗气的函数是我从自己的 https 单元借来的,它展示了如何处理 header 参数。

function QuickHTTPSGet(sURL: ansistring; out sOutREsponse: string; 
addHead: string =''; addHeadValue: string = ''): boolean;
var
htp: IXMLhttprequest;
begin

htp := ComsXMLHTTP30.create();
try
htp.open('GET', sURL, false, null, null);
if addHead <> '' then
htp.setRequestHeader(addHead, addHeadValue);
htp.send('');
result := htp.status = 200;
if result then
sOutREsponse := htp.responsetext
else
soutResponse := 'error '+inttostr(htp.status);
except
on e: Exception do begin
result := false;
sOutResponse := 'error '+e.message;
end;
end;

end;

关于Delphi HMAC SHA512 签署了对 Bittrex 交易所的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26280036/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com