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

Business Central AL中与.NET Encoding.UTF8.GetBytes(data)等效的实现方法?

解决Business Central AL中AWS SigV4认证的SignatureDoesNotMatch错误

你遇到的403 - SignatureDoesNotMatch问题,核心原因确实是AL的GenerateHash()方法默认使用系统编码(而非UTF8)将字符串转换为字节数组,这和AWS SigV4要求的UTF8编码字节序列不匹配,导致哈希结果始终不对。

第一步:实现AL中的UTF8字符串转字节数组

BC没有直接对应.NET Encoding.UTF8.GetBytes()的方法,但可以通过TextBuffer类来实现:

procedure GetUTF8Bytes(InputText: Text): Byte[]
var
    TextBuffer: TextBuffer;
    OutStream: OutStream;
    ByteArray: Byte[];
begin
    TextBuffer.Encoding := TextEncoding::UTF8;
    TextBuffer.Create();
    TextBuffer.WriteText(InputText);
    TextBuffer.Position(0);
    TextBuffer.CopyToStream(OutStream);
    ByteArray := OutStream.ToArray();
    exit(ByteArray);
end;

这个方法会将输入字符串严格按照UTF8编码转换为字节数组,完全匹配AWS的要求。

第二步:修正HMAC-SHA256哈希计算流程

放弃直接使用GenerateHash()的字符串重载,改用字节数组重载版本,确保所有参与计算的内容都用UTF8字节序列:

1. 衍生AWS SigV4签名密钥

按照AWS SigV4的规范,先从Secret Access Key衍生出Signing Key:

procedure DeriveSigningKey(SecretAccessKey: Text; DateStamp: Text; RegionName: Text; ServiceName: Text): Byte[]
var
    Cryptography: Codeunit Cryptography;
    KSecret: Byte[];
    KDate: Byte[];
    KRegion: Byte[];
    KService: Byte[];
    KSigning: Byte[];
begin
    // 初始密钥:AWS4 + SecretAccessKey(UTF8编码)
    KSecret := GetUTF8Bytes('AWS4' + SecretAccessKey);
    
    // 依次计算HMAC-SHA256
    KDate := Cryptography.GenerateHash('HMACSHA256', KSecret, GetUTF8Bytes(DateStamp));
    KRegion := Cryptography.GenerateHash('HMACSHA256', KDate, GetUTF8Bytes(RegionName));
    KService := Cryptography.GenerateHash('HMACSHA256', KRegion, GetUTF8Bytes(ServiceName));
    KSigning := Cryptography.GenerateHash('HMACSHA256', KService, GetUTF8Bytes('aws4_request'));
    
    exit(KSigning);
end;

2. 生成最终签名

将String to Sign转换为UTF8字节数组后,用Signing Key计算HMAC,再转为十六进制字符串:

procedure GenerateSignature(StringToSign: Text; SigningKey: Byte[]): Text
var
    Cryptography: Codeunit Cryptography;
    HMACBytes: Byte[];
begin
    HMACBytes := Cryptography.GenerateHash('HMACSHA256', SigningKey, GetUTF8Bytes(StringToSign));
    // 转换为AWS要求的十六进制格式
    exit(Format(HMACBytes, 0, '<Hex>'));
end;

关键注意事项

  • 统一换行符:Canonical Request和String to Sign中的换行必须是LF(\n),不能用CRLF(\r\n),AL中直接用'\n'即可,避免系统自动转换。
  • 测试数据验证:用AWS官方SigV4测试案例验证每一步的结果,比如官方提供的String to Sign和预期签名,确保衍生密钥、HMAC计算的中间结果完全匹配。
  • 避免字符串编码污染:所有参与签名的字符串(比如请求参数、日期、区域名)都要确保是纯UTF8格式,没有被其他编码转换过。

内容的提问来源于stack exchange,提问作者dewin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:19:58