Ký & Xác minh JWT

Ký JWT bằng HS256/384/512 hoặc RS256/ES256, và xác minh token bằng secret hoặc khoá công khai — kiểm chữ ký, hết hạn, alg:none riêng biệt. Chạy trong trình duyệt.

encoding

Ký & Xác minh JWT

Thuật toán
Payload (JSON)
Secret
Hết hạn sau

vd "1h", "7d" — để trống nếu không cần claim "exp"

Việc ký diễn ra trong trình duyệt bằng WebCrypto. Khoá riêng dán vào đây không rời khỏi tab — nhưng đừng ký token production bằng công cụ trình duyệt, hãy dùng backend của bạn.

What next?

FAQ

Tool này khác gì với jwt-decoder trên cùng site?

jwt-decoder chỉ đọc token — nó giải mã Base64URL phần header và payload rồi hiển thị các claim ra, nhưng không bao giờ kiểm tra chữ ký. Điều đó đủ dùng cho câu hỏi "token này nói gì", nhưng không trả lời được câu "token này có đáng tin không", vì một token bị giả mạo hoàn toàn với payload tuỳ ý vẫn giải mã ra sạch sẽ y như token thật. Tool này thì thực sự chạy bước xác minh mật mã học: nó tự tính lại chữ ký từ header và payload bằng secret hoặc khoá công khai bạn cung cấp, so khớp từng byte với chữ ký có trong token, và chỉ báo cáo các claim thời gian sau khi bước đó qua. Nếu bạn chỉ cần xem nội dung token mà không có sẵn khoá, jwt-decoder là lựa chọn đúng; nếu cần biết token có đáng tin hay không, dùng tool này.

Vì sao kết quả trả về ba trạng thái khác nhau thay vì chỉ "hợp lệ / không hợp lệ"?

Vì "không hợp lệ" thực ra gộp chung ba kiểu lỗi khác hẳn nhau, mỗi kiểu cần cách xử lý riêng. Chữ ký sai (invalidSignature) nghĩa là token được ký bằng khoá khác với khoá bạn đưa vào — sai secret, sai khoá công khai, hoặc payload đã bị ai đó chỉnh sửa. Hết hạn (expired) nghĩa là chữ ký hoàn toàn hợp lệ; người phát hành token đã làm đúng mọi thứ, chỉ là token sống lâu hơn giá trị claim "exp" cho phép — cách xử lý là lấy token mới, không phải nghi ngờ có giả mạo. Thuật toán bị từ chối (algRejected) nghĩa là header token khai báo một thuật toán khác với thuật toán bạn chọn để kiểm tra — có thể do cấu hình lệch nhau, hoặc trong trường hợp xấu nhất là một cuộc tấn công. Gộp cả ba vào một nhãn "invalid" duy nhất sẽ không giúp ích gì cho người đang debug lỗi 401, vì họ cần biết chính xác đang gặp phải kiểu nào trong ba kiểu rất khác nhau đó.

alg: "none" là lỗ hổng JWT nào, và tool này chặn bằng cách nào?

Một số thư viện JWT đời đầu chấp nhận token có header khai "alg": "none" và coi chữ ký rỗng là hợp lệ tự động — thư viện thấy "không yêu cầu thuật toán" nên bỏ luôn bước kiểm tra, nghĩa là bất kỳ ai cũng giả mạo được token với claim tuỳ ý chỉ bằng cách đặt đúng trường header đó rồi không thêm gì sau dấu chấm cuối cùng. Tool này né hẳn cả nhóm lỗi này bằng cách không bao giờ hỏi "header có bảo bỏ qua xác minh không" ngay từ đầu: bạn chọn trước thuật toán mình kỳ vọng (HS256, RS256…), và kỳ vọng đó được áp dụng như một allow-list tường minh thông qua tham số algorithms của thư viện jose. Nếu header token khai bất kỳ thứ gì khác — kể cả "none" — việc xác minh bị từ chối ngay trước khi động tới khoá, đúng cách một thư viện backend cẩn trọng về bảo mật nên hành xử. Cách này cũng chặn luôn kiểu tấn công "alg confusion" kinh điển: dùng khoá công khai RS256 làm secret HMAC để xác minh một chữ ký HS256 giả — vì tool luôn khoá cứng thuật toán kiểm tra theo lựa chọn của bạn, không bao giờ đọc thuật toán từ chính token để quyết định cách kiểm tra nó. Điều này khác hẳn jwt-decoder: theo đúng RFC 7519 §6, một "unsecured JWT" là token có alg: "none" và phần chữ ký để trống, và vì jwt-decoder chỉ đọc chứ không xác minh, nó vẫn giải mã được token dạng đó bình thường rồi gắn nhãn cảnh báo "Unsecured" lên trên — hiển thị đúng những gì token khai chứ không phán xét gì thêm. Tool ký & xác minh này thì ngược lại: khi bạn đưa một token alg: none vào để xác minh, nó luôn bị từ chối thẳng, không có đường nào để "đọc thành công" một token như vậy trong tab Xác minh.

Chữ ký hợp lệ có nghĩa là token vẫn còn dùng được không?

Không nhất thiết — đây chính là lý do có trạng thái expired tách riêng khỏi valid. Chữ ký chỉ chứng minh token đến từ đúng người giữ khoá và chưa bị ai chỉnh sửa nội dung; nó không nói gì về việc token có còn "sống" hay không. Một token với chữ ký hoàn toàn đúng nhưng claim exp đã ở quá khứ vẫn trả về trạng thái expired, kèm phần chi tiết ghi rõ "Signature is valid, but the exp claim is in the past". Tương tự, nếu claim nbf (not-before) còn ở tương lai, tool báo notYetValid dù chữ ký vẫn đúng. Chỉ khi mọi claim thời gian đều hợp lệ chữ ký khớp thì kết quả mới là valid, kèm dòng chữ xác nhận cả hai điều kiện đã qua.

Định dạng khoá cần cho RS256 / ES256 là gì?

Khi ký, tool cần khoá riêng PEM chuẩn PKCS#8 (khối bắt đầu bằng -----BEGIN PRIVATE KEY-----). Khi xác minh, tool cần khoá công khai PEM chuẩn SPKI (-----BEGIN PUBLIC KEY-----). Đây đúng là hai định dạng mà crypto.subtle.importKey của WebCrypto đọc hiểu trực tiếp — thư viện jose mà tool dùng chỉ là lớp bọc gọn hơn cho WebCrypto, không tự chế cơ chế đọc khoá riêng. Khoá PKCS#1 kiểu cũ (-----BEGIN RSA PRIVATE KEY-----) là một cách mã hoá khác mà WebCrypto không đọc thẳng được; cần chuyển đổi bằng openssl pkcs8 -topk8 -nocrypt trước khi dán vào.

Có nên ký token production bằng công cụ chạy trong trình duyệt này không?

Xác minh thì rủi ro thấp: bạn chỉ dán vào một khoá công khai hoặc một secret dùng chung mà bạn vốn đã tin tưởng bên nhận giữ, và không có gì bạn gõ vào bị gửi đi đâu — toàn bộ việc kiểm tra chạy bằng WebCrypto ngay trong tab này. Việc ký mới là chỗ cần cân nhắc kỹ: một khoá riêng bạn dán vào bất kỳ tab trình duyệt nào sẽ bị phơi ra cho JavaScript của tab đó suốt thời gian tab mở, và cho bất kỳ ai/tiện ích mở rộng độc hại nào có quyền truy cập thiết bị trong lúc đó. Với một token test dùng bỏ, đánh đổi này chấp nhận được để lấy sự tiện lợi; với khoá riêng bảo vệ một hệ thống production thật, hãy ký bằng backend hoặc pipeline CI của bạn với thư viện phía server đã qua kiểm định, đúng lời cảnh báo mà các tool tạo khoá khác trên site này cũng đã ghi.

More encoding tools