KeyGenerator.io

JWT 密鑰產生器

HS256、HS384、HS512 用的 HMAC 簽章密鑰,在你的瀏覽器裡產生。不連網,不記錄,不上傳。

0 位元熵

密鑰長度
編碼

空白鍵 換一個,C 複製。密鑰由本機的 crypto.getRandomValues 產生,頁面不載入任何外部資源。

這串密鑰是怎麼產生的

以 HS256、HS384 或 HS512 簽發的權杖,驗證時用的是同一把密鑰。它不是密碼:沒有人要輸入它,也沒有人需要記住它,更不該唸得出來。它是一串隨機位元組,存放在環境變數或密鑰管理服務裡,唯一的任務就是讓人猜不到。

這裡的位元組直接取自 crypto.getRandomValues,也就是瀏覽器的密碼學安全亂數產生器,再以十六進位或 Base64 寫出。整條路徑上沒有時間戳、沒有計數器,也沒有 Math.random。選 256 位元會得到 32 個隨機位元組,384 位元是 48 個,512 位元是 64 個 —— 長度對應該演算法所用的雜湊。

全部在你自己的裝置上完成。頁面載入後不發出任何網路請求,所以螢幕上這串密鑰從未在別處存在過,也不會傳到任何地方。重新整理就永遠消失。

常見問題

JWT 密鑰要多長才夠?

至少要和簽發演算法的雜湊輸出一樣長:HS256 是 32 位元組(256 位元),HS384 是 48 位元組,HS512 是 64 位元組。HMAC 會把超過區塊長度的密鑰再雜湊一次壓回來,所以 200 位元組並不會比 64 位元組實質更強。真正的風險在於取得比這更短。

十六進位和 Base64 哪個比較安全?

一樣安全。它們是同一串隨機位元組的兩種寫法 —— 32 個位元組寫成十六進位是 64 個字元,寫成 Base64 大約 44 個字元,強度完全相同。用你的函式庫預期的那種即可。如果這個值要經過設定檔或 shell 腳本,十六進位比較保險,因為它只含 0-9 和 a-f。

什麼時候該用 Base64URL?

Base64URL 把 + 和 / 換成 - 和 _,並去掉補位字元,因此可以直接放進網址、查詢字串或檔名而不必再跳脫。其他場合用標準 Base64 就好。JWT 本身確實採用 Base64URL 編碼,但那說的是權杖,不是用來簽發它的密鑰。

可以直接拿密碼或通關密語當密鑰嗎?

可以,而這正是 HMAC 簽章最常見的破口。好記的句子所帶的熵遠低於它的長度看起來的樣子,而攻擊者只要手上有一個有效權杖,就能離線以硬體極限的速度逐一試出候選密鑰,沒有任何次數限制擋得住。請用隨機位元組。

在網頁裡產生密鑰安全嗎?

這完全取決於這個頁面能不能把它送出去,而這件事你可以自己查證,不必只是相信。打開瀏覽器開發者工具切到「網路」分頁,然後隨便產生幾次:這個頁面載入之後不發出任何請求。它背後沒有伺服器端,因為它根本沒有伺服器端可言。

密鑰該放在哪裡?

放在環境變數裡,有密鑰管理服務就放進去。絕對不要放進程式庫 —— 一旦提交進 git,即使之後刪掉也還留在歷史紀錄裡,而歷史會被複製、被 fork、被備份。如果已經提交過,唯一有效的補救是更換密鑰。

多久該更換一次?

照一個你真的做得到的週期,並在懷疑外洩時立刻更換。實務上的阻力在於:更換會讓所有以舊密鑰簽發的權杖失效。需要在不強制登出的情況下輪替的系統,通常會設一段並行期 —— 用新密鑰簽發,同時接受新舊兩把驗證,之後再淘汰舊的。

這個也能用在 RS256 或 ES256 嗎?

不行。那兩者是非對稱的:用私鑰簽發、用對應的公鑰驗證,需要的是一組金鑰對而不是共用密鑰。這個頁面產生的是對稱式 HMAC 密鑰,也就是 HS 系列所使用的。如果簽發方和驗證方是不同的組織,通常反而該選非對稱演算法。

你們看得到我產生的密鑰嗎?

看不到,也沒有任何東西能看到。這個頁面是一份靜態 HTML,樣式和程式碼都內嵌其中;送到你的瀏覽器之後,不再載入任何東西,也不送出任何東西。沒有分析工具、沒有字型、沒有第三方腳本,也沒有任何可以記錄的伺服器。