各位前輩:
我使用 Deplhi 10 Seattle 編寫一支Https網站的介接API(文件規範如附圖),在程式執行時對方傳回"Token簽章驗證錯誤",但一直找不出問題所在。如有前輩能幫我解決問題我願付出新台幣2000元感謝。請先mail通知我告知您可以解決,避免多位前輩同時解答。然後我將mail給您我的程式碼幫我解決問題。也可以直接提供您的程式碼。
文件中測試站號:@Z5S
Sercert Key:@Z5S-9w?LJ$7k3z=NgR4*+5dSDq!8a&2FZ6n-
我的email:chiaomuo@yahoo.com.tw
幫你問 Claude AI 了(不用錢)
沒測過不確定OK不OK
你自己看著辦
program JWTGenerator;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.NetEncoding,
System.Hash,
IdSSLOpenSSL,
IdSSLOpenSSLHeaders,
IdGlobal;
function Base64UrlEncode(const Input: string): string;
var
Encoder: TBase64Encoding;
begin
Encoder := TBase64Encoding.Create(0);
try
Result := Encoder.Encode(Input);
// URL-safe base64
Result := StringReplace(Result, '+', '-', [rfReplaceAll]);
Result := StringReplace(Result, '/', '_', [rfReplaceAll]);
Result := StringReplace(Result, '=', '', [rfReplaceAll]);
finally
Encoder.Free;
end;
end;
function HMACSHA256(const Message, Key: string): TBytes;
var
Context: PHMAC_CTX;
DigestLength: Cardinal;
Digest: TBytes;
begin
Context := HMAC_CTX_new;
try
if HMAC_Init_ex(Context, @Key[1], Length(Key), EVP_sha256, nil) <> 1 then
raise Exception.Create('HMAC初始化失敗');
if HMAC_Update(Context, @Message[1], Length(Message)) <> 1 then
raise Exception.Create('HMAC更新失敗');
SetLength(Digest, EVP_MAX_MD_SIZE);
if HMAC_Final(Context, @Digest[0], DigestLength) <> 1 then
raise Exception.Create('HMAC完成失敗');
SetLength(Digest, DigestLength);
Result := Digest;
finally
HMAC_CTX_free(Context);
end;
end;
var
Header, Payload: string;
EncodedHeader, EncodedPayload: string;
Message, SecretKey: string;
Signature: TBytes;
EncodedSignature: string;
FinalToken: string;
begin
try
// 1. 準備 Header 和 Payload
Header := '{"alg":"HS256","typ":"JWT"}';
Payload := '{"sub":"@Z5S","aud":"MOENV","iat":"1723000000"}';
// 2. Base64Url 編碼
EncodedHeader := Base64UrlEncode(Header);
EncodedPayload := Base64UrlEncode(Payload);
// 3. 準備簽名訊息
Message := EncodedHeader + '.' + EncodedPayload;
SecretKey := '@Z5S-9w?LJ$7k3z=NgR4*+5dSDq!8a&2FZ6n-';
// 4. 計算 HMAC-SHA256 簽名
Signature := HMACSHA256(Message, SecretKey);
// 5. 對簽名進行 Base64Url 編碼
EncodedSignature := Base64UrlEncode(TEncoding.ASCII.GetString(Signature));
// 6. 組合最終的 JWT
FinalToken := Message + '.' + EncodedSignature;
// 7. 輸出結果
WriteLn('JWT Token:');
WriteLn(FinalToken);
ReadLn; // 等待使用者按下 Enter
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.