HS256 使用一個共用密鑰搭配 HMAC-SHA-256 為 JWT 簽章,而 RS256 則使用一把 RSA 私鑰進行簽署,其對應的公鑰任何人都可以用來驗證。兩者之間的選擇取決於誰需要檢查這個權杖:對稱密鑰適用於單一信任邊界之內,非對稱金鑰組則適用於許多獨立的參與方必須在不共用簽署素材的情況下進行驗證。一個僅在瀏覽器中運作的 HS256 工具,例如 JWT Generator,涵蓋了大多數的本機開發、整合測試以及單一網域的權杖工作流程,無需佈建憑證或上傳任何資料,因為所有處理都透過當前分頁的 Web Crypto 執行。RS256 則需要不同的工具鏈,因為簽署者需要持有私鑰,而驗證者需要對應的公鑰。本文的其餘部分將逐步說明 JWT Generator 實際輸出的內容、如何準備其嚴格的 JSON 聲明 (claims) 與足夠長度的 HMAC 密鑰,以及在將權杖提升至正式環境之前,如何透過一個持續維護的 JOSE 函式庫來驗證結果。

HS256 vs RS256:瀏覽器權杖工具背後的選擇
在 RFC 7515 所定義的 JSON Web Signature 領域中,有兩種演算法佔據主導地位。HS256 是建立在 HMAC 之上並使用 SHA-256 雜湊的訊息驗證碼 (Message Authentication Code)。同一組位元字串同時作為簽署金鑰與驗證金鑰,因此每一個驗證權杖的參與方都必須持有它。RS256 定義於 RFC 7518,是一種基於 RSASSA-PKCS1-v1_5 與 SHA-256 的非對稱簽章。簽署者持有 RSA 私鑰,而驗證者僅需要對應的公鑰,通常透過 JWKS 端點、靜態憑證或 PEM 檔案來發布。
實務上的問題並非哪種演算法在抽象意義上比較好;而是誰必須驗證這個權杖。在同一個程式碼庫中簽發並消費自家權杖的後端服務,會因為只需管理單一密鑰、且輪替只需一次替換而受益於 HS256。由單一組織簽發、卻被數十個獨立用戶端(身分提供者、聯盟 API 或開放平台)所消費的權杖,則會因為用戶端只需要公鑰即可檢查簽章、無需持有簽署素材而受益於 RS256。僅在瀏覽器中運作的工具通常以 HS256 為目標,因為將 RSA 私鑰帶入一個公開的網頁將使其失去意義。
如果搜尋「generate JWT token online RS256」是出於需要以公鑰進行驗證的需求,那麼瀏覽器工具很可能不是正確的答案;這時需要的是擁有私鑰的本機 CLI 或伺服器端處理程序。若搜尋是出於 HS256 即可勝任的開發任務(本機 API 測試、GitHub App 驗證、單一邊界內的服務對服務權杖),那麼瀏覽器工具將是最快的途徑。
JWT Generator 的輸出格式
JWT Generator 只會輸出唯一的東西:一個精簡 (compact) 形式的 JSON Web Signature,其受保護標頭 (protected header) 固定為 alg: HS256, typ: JWT。固定演算法是一項刻意的決定:它可以防止權杖被悄悄切換成 none、不相符的非對稱演算法,或任何目的端系統未預期接受的其他值。簽署後的輸出是由句點分隔的三段 base64url 字串 —— header.payload.signature —— 使用 URL 安全字母表編碼且不含等號填補,如 RFC 7515 所規範。
該產生器只接受兩個輸入,不接受其他東西。第一個是嚴格的 JSON 聲明物件;若其頂層包含陣列、以 null 作為根節點、註解、尾端逗號、undefined、NaN、Infinity 或任何 JavaScript 運算式,將會被拒絕。第二個是至少 32 位元組長度的 UTF-8 密鑰,這對應到與 256 位元雜湊輸出相關的 HS256 金鑰長度下限。提供了一個隨機按鈕供測試之用;它會產生 32 個密碼學上安全的隨機位元組,並以 64 個十六進位字元顯示。請將這些位元組視為可見的開發素材,而非自動佈建的正式環境密鑰。
| 屬性 | HS256 (JWT Generator) | RS256 (此處不支援) |
|---|---|---|
| 演算法類別 | MAC,對稱 | 簽章,非對稱 |
| 金鑰素材 | 共用密鑰,至少 32 個 UTF-8 位元組 | RSA 私鑰 (簽署者) 加上 RSA 公鑰 (驗證者) |
| 驗證者需求 | 與簽署者相同的密鑰 | 僅需公鑰,透過 JWKS、憑證或 PEM 發布 |
| 典型使用情境 | 單一信任網域、內部 API、GitHub Apps、本機測試 | 聯盟身分、第三方驗證、開放平台 |
| 瀏覽器工具支援 | 透過 Web Crypto 原生支援,無需上傳 | 在公開頁面中並不安全 —— 私鑰將會外洩 |
| 參考規範 | RFC 7518,使用 SHA-256 的 MAC | RFC 7518,使用 SHA-256 的 RSASSA-PKCS1-v1_5 |
如果目的端明確要求 RS256,JWT Generator 並不會產生。這道界線是有意為之的:在公開的網頁中產生 RS256 權杖將需要上傳或輸入私鑰,這會摧毀在本機執行的價值。在這種情況下,伺服器端腳本、由 OpenSSL 驅動的 CLI,或是持續維護的函式庫才是正確的工具。
準備聲明物件與 HMAC 密鑰
在點擊任何按鈕之前,請先明確決定目的服務所預期的聲明項目。該產生器不會自動加入 iat、exp、nbf、iss、sub、aud、jti 或任何其他標準聲明。您必須負責提供具權威性的數值:iss 與 aud 必須與驗證者所檢查的內容一致,而任何 exp 值都必須以自 Unix 紀元起的秒數表示,而非 JavaScript 的毫秒數。像 1717500000 這樣的數值是秒數;對應的毫秒數則會是 1717500000000。將兩者混淆是權杖看起來有效卻無法通過驗證的最常見原因之一。
請保持 JSON 物件的嚴格符合性。以下是符合許多 API 預期的聲明結構:
- iss —— 簽發者字串,例如服務名稱或租戶識別碼
- sub —— 主體識別碼,通常是被驗證的使用者或系統
- aud —— 接收方字串,必須與接收服務自我標示的名稱完全一致
- iat —— 簽發時間,以紀元秒為單位
- exp —— 過期時間,以紀元秒為單位
- jti —— 唯一權杖識別碼,當服務需要追蹤重放時使用
關於密鑰,請貼上一組至少 32 個 UTF-8 位元組的非正式環境字串,或點擊隨機按鈕以取得一個 64 字元的十六進位值。請記住,非 ASCII 文字的字元數與位元組數並不相同:由單位元組 ASCII 字元組成的 32 字元密碼正好是 32 位元組,但 32 個表情符號字符通常會編碼為約 128 位元組。此檢查是基於位元組,而非字元。
產生、檢查並複製 HS256 權杖
備妥聲明與密鑰後,實際的產生流程分為三個步驟。該工具的設計使每一步都會產生可檢視的產物 —— 權杖輸出絕不應被視為不透明的黑盒子。
- 將嚴格的 JSON 聲明物件貼入聲明欄位,並輸入一組至少 32 位元組的非正式環境 UTF-8 密鑰,或透過隨機按鈕產生測試素材。
- 產生 HS256 權杖並檢視三段精簡區段:固定的標頭 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9、經 base64url 編碼的酬載 (payload),以及經 base64url 編碼的簽章。標頭將永遠解碼為 {"alg":"HS256","typ":"JWT"}。請確認聲明輸出與您所輸入的內容完全一致,且未夾帶任何機密資料 —— 密碼、私鑰或個人紀錄。
- 複製該權杖,並使用目標 JOSE 函式庫搭配明確指定的演算法、簽發者、接收方、生命週期與金鑰政策來進行驗證。切勿僅憑該產生器就將權杖提升至預備或正式環境。
檢視各區段時,有兩項中繼資料值得留意。首先,區段長度具有參考價值:一個精簡的 HS256 權杖長度大約是原始酬載的 1.5 倍,再加上固定的標頭與一段 43 字元的簽章。短於預期通常意味著聲明物件被截斷了;長於預期則通常意味著解析器雖然接受了該 JSON,但其中嵌入了服務並未預期的內容。其次,產生器本身的輸出並未自我驗證。請將該頁面視為簽署者,而非驗證者。若要確認權杖能正確完成往返 (round-trip),請將其貼入解碼器(例如 JWT Decoder),並交叉比對標頭與酬載區段是否與您輸入的內容一致。
使用正式環境的 JOSE 函式庫驗證產生的權杖
即使是能輸出語法正確權杖的瀏覽器工具,也無法確保目的端會接受它。驗證作業應屬於正式環境的程式碼庫,而非產生頁面。請將複製下來的權杖傳遞給目標 JOSE 函式庫 —— jsonwebtoken、jose、PyJWT、java-jwt 或目標技術堆疊中的等效函式庫 —— 並明確執行下列四項政策檢查。
第一,鎖定 (pin) 演算法。應告知該函式庫僅接受 HS256,並拒絕任何其他 alg 值,包括 none。演算法混淆攻擊正是利用了那些願意接受標頭所宣告之任何值的驗證者。第二,將 iss 與 aud 作為完全相符的字串進行驗證,而非以子字串或正規表示式比對,並對照簽發者與目的端所設定的值。第三,以一小段記載於安全模型中的時鐘偏移容忍量檢查 exp、nbf 與 iat;對於僅僅因為早了一毫秒就過期而拒絕權杖的情況,這通常並非預期的行為。第四,請透過與服務其他部分相同的密鑰管理路徑來提供密鑰或金鑰,而非透過在測試中被覆寫的環境變數。
RFC 7515 是精簡序列化格式的權威參考,而 RFC 7518 則是密碼學演算法本身的權威參考。當產生器的輸出與函式庫的讀取結果不一致時,爭議幾乎總是出在聲明值、演算法不符,或驗證者尚未套用某次的金鑰輪替。請將產生器視為忠實的簽署者;將函式庫視為接受與否的真理來源。
When You Actually Need RS256 and How to Switch
If the destination specifically requires RS256 — because it fetches a JWKS, validates against a public certificate, or rejects HS256 outright — a browser-based HS256 generator is the wrong tool and should not be adapted. RS256 verification expects the verifier to hold the public half of an RSA key pair and the signer to hold the private half. Importing a private key into a public web page destroys the security property that justifies the algorithm. The right paths are:
- A local CLI driven by openssl or by a maintained JWT library that reads a PEM private key from disk and signs locally
- A server-side script invoked from CI that uses the project's own signer, not a public web form
- A maintained JOSE library inside the issuing service, where the private key never leaves the trust boundary
For workflows that are happy with HS256, the JWT Generator remains a complete browser-based signer. For GitHub App authentication specifically, where HS256 is the documented requirement, the dedicated HS256 GitHub App guide walks through the exact claim shape and expiration policy that GitHub's API expects.
Two final cautions apply to both algorithms. Copying or displaying a token can expose bearer credentials through clipboard history, screenshots, browser extensions, logs, support tickets, or chat — only non-production claims and secrets should appear on any generator page. If a real secret or active token is pasted into any environment outside its intended boundary, rotate or revoke it rather than assuming the local implementation made disclosure harmless. The browser is a useful shortcut for development, not a safe home for production credentials.
For a deeper look, see Set Up a Shortcut for Arrow Functions in VS Code.