JWT 的簽章演算法,表面上是在選「怎麼簽名」,實際上也在決定:
哪些服務有能力發出一張看起來合法的 Token?
專案目前是單體架構,Token 由同一個應用程式簽發與驗證。但如果日後拆成認證、訂單、付款三個服務,情況就不一樣了,如下表:

訂單和付款服務只需要確認:
「這張 Token 是認證服務發的,而且沒有被竄改。」
它們其實不應該擁有簽發 Token 的能力。
這就是 HS256 和 RS256 真正的差異。
【HS256採對稱加密、RS256採非對稱加密。】
HS256 和 RS256 最大的差別,不是「哪個比較安全」,而是簽發和驗證需要什麼鑰匙。以上面的三個服務為例:
| 服務 | HS256 持有 | 能否簽發 | RS256 持有 | 能否簽發 |
|---|---|---|---|---|
| 認證服務 | secret | ✓ | 私鑰 | ✓ |
| 訂單服務 | secret | ✓ | 公鑰 | ✗ |
| 付款服務 | secret | ✓ | 公鑰 | ✗ |
在HS256 使用同一把 secret的情況下,如果訂單服務被入侵,攻擊者拿到 secret 後,不只是能驗證現有 Token,還能自己簽一張新的 Token。
只要簽章也正確,其他服務就無法從 Token 本身判斷:
「這不是認證服務簽的,是被入侵的訂單服務自己簽的。」
而RS256 則把能力拆成兩把鑰匙:

私鑰負責簽發,公鑰負責驗證。
因此:
驗證方可以知道「這是真的」,卻不需要因此取得「我也可以製造真的 Token」的能力。
這才是 RS256 對架構最大的價值。
如果目前就是單體,同一個應用程式既要簽發又要驗證,那麼即使開成兩台,兩台都需要簽發能力。
這時使用 HS256 並沒有因為「機器變多」就突然變得不安全,因為兩台本來就都是 Token 的簽發方。

所以RS256 並不是因為服務變多就一定比較好,而是當「需要驗證的人」和「可以簽發的人」開始不同時,才真正產生價值。
以目前本專案的單體架構來說,用 HS256 完全是可以的。
因為希望 Token 的設計從一開始就把「簽發」和「驗證」拆開。日後如果真的拆出只需要驗證的服務,它只需要拿到公鑰,不必重新設計整套認證機制。
這個選擇換到的是日後的彈性:單體的每一台都持有同一把私鑰,散布範圍和 HS256 的 secret 一樣。
選擇 RS256 之後,還多了幾件事情需要處理:
整合測試則在啟動時產生丟棄式 RSA 金鑰,避免測試依賴開發環境裡的實體金鑰。