如何用Delphi生成Azure Cosmos DB签名?C#与Delphi结果不一致
Delphi与C#生成HMACSHA256签名不一致的解决方法
我之前也踩过这个坑,核心问题就是Delphi和C#在处理HMACSHA256的编码规则、哈希输出格式这两个环节没对齐,咱们一步步来修正:
先明确C#的核心逻辑(微软示例的常规写法)
首先得确认你用的C#代码逻辑,微软官方的Cosmos DB签名示例一般是这样的:
using System.Security.Cryptography; using System.Text; var data = "要签名的原始请求内容"; // 比如HTTP请求的拼接字符串 var key = "你的Cosmos DB账户密钥"; // 1. 用UTF-8编码将字符串转成字节数组 var dataBytes = Encoding.UTF8.GetBytes(data); var keyBytes = Encoding.UTF8.GetBytes(key); // 2. 生成HMACSHA256哈希 using (var hmac = new HMACSHA256(keyBytes)) { var hashBytes = hmac.ComputeHash(dataBytes); // 3. 将哈希字节数组转成Base64字符串 var signature = Convert.ToBase64String(hashBytes); }
你得到的2LuKbSl8RkLc0eKhjQv4oCpXzRcmR02L9sDfSxSB5HA=就是这个Base64格式的结果。
为什么你的Delphi代码会出错?
你用的THashSHA2.GetHMAC(Data, Key)有两个关键问题:
- 编码不统一:Delphi默认用系统ANSI编码把字符串转成字节数组,而C#用的是UTF-8,输入的字节序列不一样,哈希结果肯定不同。
- 输出格式不符:
GetHMAC返回的是哈希的十六进制字符串(就是你看到的2ca409c9a26aa3ed...),但C#输出的是Base64格式,两者自然无法匹配。
修正后的Delphi代码
咱们把编码和输出格式完全对齐C#的逻辑,写一个适配函数:
uses System.SysUtils, System.Hash, System.NetEncoding; function GenerateCosmosHMAC(const AData, AKey: string): string; var DataBytes, KeyBytes, HashBytes: TBytes; begin // 第一步:用UTF-8编码转换字符串到字节数组,和C#保持一致 DataBytes := TEncoding.UTF8.GetBytes(AData); KeyBytes := TEncoding.UTF8.GetBytes(AKey); // 第二步:生成HMACSHA256的哈希字节数组 HashBytes := THashSHA2.GetHMACAsBytes(DataBytes, KeyBytes); // 第三步:将哈希字节转成Base64字符串,对应C#的Convert.ToBase64String Result := TNetEncoding.Base64.EncodeBytesToString(HashBytes); end;
额外需要注意的细节
- 确保你传入的
AData和C#中的data完全一致:比如HTTP请求的拼接内容(包括换行符是\r\n还是\n、请求头顺序、大小写),哪怕一个字符差异,签名都会出错。 - 密钥
AKey也要和C#中使用的完全相同,注意不要有前后空格,编码必须是UTF-8。
调用这个函数后,生成的签名应该就和C#的结果完全匹配了。
内容的提问来源于stack exchange,提问作者Leo Lui
相关产品推荐
相关产品推荐

