如何将C#实现SHA256哈希转Base64Url的代码改写为Delphi 11?
Delphi 11 实现 Xero 授权链接生成(对应C#示例代码)
你当前的代码存在核心问题:错误地对SHA256哈希的十六进制字符串进行Base64Url编码,而Xero要求的是对code verifier的UTF-8字节执行SHA256哈希后,直接对哈希的原始字节数组做Base64Url编码。以下是完整的Delphi 11实现,完全对应你提供的C#示例逻辑:
完整实现代码
uses System.SysUtils, System.Hash, System.NetEncoding, System.Classes; // 按钮点击事件处理函数,对应C#的btnGenerateLink_Click procedure TForm1.btnGenerateLinkClick(Sender: TObject); const AuthorisationUrl = 'https://login.xero.com/identity/connect/authorize'; // Xero官方授权地址 var ClientID, Scopes, RedirectURI, State: string; CodeVerifierBytes, HashBytes: TBytes; CodeChallenge: string; AuthLink: string; begin // 1. 获取输入框内容 ClientID := txtBoxClientID.Text; Scopes := TNetEncoding.URL.Encode(txtBoxScopes.Text); // 对应C#的Uri.EscapeUriString RedirectURI := txtBoxRedirectURI.Text; State := txtBoxState.Text; // 2. 生成Code Challenge(核心逻辑) // 将Code Verifier转为UTF-8字节数组 CodeVerifierBytes := TEncoding.UTF8.GetBytes(txtBoxCodeVerifier.Text); // 计算SHA256哈希,得到原始字节数组 HashBytes := THashSHA2.GetHashBytes(CodeVerifierBytes, SHA256); // 对哈希字节做Base64Url编码(自动处理去掉=、替换+/-、/_) CodeChallenge := TBase64UrlEncoding.EncodeBytesToString(HashBytes); // 3. 拼接授权URL AuthLink := Format('%s?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&state=%s&code_challenge=%s&code_challenge_method=S256', [AuthorisationUrl, TNetEncoding.URL.Encode(ClientID), // 对参数转义避免特殊字符破坏URL TNetEncoding.URL.Encode(RedirectURI), Scopes, TNetEncoding.URL.Encode(State), TNetEncoding.URL.Encode(CodeChallenge)]); // 4. 更新界面状态 txtBoxAuthLink.Text := AuthLink; btnAuthorise.Enabled := True; end;
关键修正点说明
哈希处理逻辑:
- 替换
THashSHA2.GetHashString为THashSHA2.GetHashBytes,获取SHA256哈希的原始字节数组,而非十六进制字符串 - 先将code verifier转为UTF-8字节数组再计算哈希,和C#的
Encoding.UTF8.GetBytes逻辑完全对齐
- 替换
Base64Url编码:
- 使用Delphi自带的
TBase64UrlEncoding.EncodeBytesToString直接处理哈希字节数组,该方法自动完成:- 移除末尾的
=填充字符 - 将
+替换为-,/替换为_
- 移除末尾的
- 无需手动创建
TBase64UrlEncoding实例,直接调用类方法更简洁可靠
- 使用Delphi自带的
URL参数转义:
- 对
ClientID、RedirectURI、State、CodeChallenge补充URL转义(C#示例仅转义了Scopes,但实际所有参数都应转义避免特殊字符导致URL失效) - 使用
TNetEncoding.URL.Encode对应C#的Uri.EscapeUriString
- 对
内容的提问来源于stack exchange,提问作者Paul Coshott
相关产品推荐
相关产品推荐

