You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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)有两个关键问题:

  1. 编码不统一:Delphi默认用系统ANSI编码把字符串转成字节数组,而C#用的是UTF-8,输入的字节序列不一样,哈希结果肯定不同。
  2. 输出格式不符: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:05:39