我的项目需要通过REST API连接Azure Cosmo数据库。 Azure Cosmo数据库连接需要将HMACSHA256签名传递给HTTP标头。我尝试在Delphi 10.2中使用THashSHA2.GetHMAC(Data,Key)函数来获取此签名。为了验证结果,我在C#中运行示例代码(从MS下载)以验证Delphi生成的结果。不幸的是,他们不一样! C#:2LuKbSl8RkLc0eKhjQv4oCpXzRcmR02L9sDfSxSB5HA = 德尔福:2ca409c9a26aa3ed6c772b6bda5bbe66bcd0d929c3ca4359f19ea42314437e5a 我通过在线HMACSHA256发生器验证了Delphi的结果。德尔福是正确的。
我在网上搜索了另一种生成签名的方法。我得到了TIdHMACSHA256(使用IdSSLOpenSSL.LoadOpenSSLLibrary)。我尝试了代码但也没有运气。结果(96OyCOmXzODAP9CljJgleuG5J5c4nIDeiSlr3hdcpYY =)也与C#生成的结果不同。
我注意到C#代码运行Convert.FromBase64String(key)将密钥转换为byte,生成散列,然后将Convert.ToBase64String(hashPayLoad)转换为签名。我怀疑Delphi中的错误结果是缺少这种步骤。但我不知道该怎么做。
有没有人有使用Delphi生成Azure Cosmo数据库签名的经验?请帮忙!
答案 0 :(得分:0)
在搜索了所有可能的网站和大量的反复试验后,我终于得到了解决方案。结果与从C#生成的签名相同。代码已从“https://www.delphipraxis.net/190563-dxe7-indy-hmac-sha256-encoding.html”
修改function GenerateCosmosDBSignature(const AData,AKey:string):string; VAR AHMAC:TIdBytes; bytes:TBytes;
开始
IdSSLOpenSSL.LoadOpenSSLLibrary;
如果不是TIdHashSHA256.IsAvailable那么
raise Exception.Create('SHA-256 hashing is not available!');
使用TIdHMACSHA256.Create做
试
//original
//Key := IndyTextEncoding_UTF8.GetBytes(AKey);
//AHMAC := HashValue(IndyTextEncoding_UTF8.GetBytes(AData));
//after modified
Key := TIdBytes(TNetEncoding.Base64.DecodeStringToBytes(AKey));
AHMAC := HashValue(IndyTextEncoding_UTF8.GetBytes(AData));
最后
Free;
端;
//原始
// result:= TIdEncoderMIME.EncodeBytes(AHMAC);
//修改后的
result:= AnsiString(TNetEncoding.Base64.EncodeBytesToString(System.TArray(AHMAC)));
端;
答案 1 :(得分:0)
使用Delphi System.Hash
获取Cosmos DB签名的另一种方法function GenerateCosmosDBSignature(const AData,AKey:string):string; VAR keyBytes,dataBytes:TBytes;
开始
keyBytes:= TNetEncoding.Base64.DecodeStringToBytes(AKEY); 数据字节:= TEncoding.UTF8.GetBytes(ADATA);
result:= AnsiString(TNetEncoding.Base64.EncodeBytesToString(THashSHA2.GetHMACAsBytes(dataBytes,keyBytes)));
端;