Đang xử lý.....

Mã thông báo web JSON – JSON Web Token (JWT)  

Giới thiệu Mã thông báo web JSON (JWT) là một phương tiện nhỏ gọn, an toàn URL để thể hiện các phản hồi được chuyển giao giữa máy chủ và ứng dụng nhằm xác thực quyền truy cập. Các khiếu nại hay phản hồi trong JWT được mã hóa dưới dạng đối tượng JSON được sử dụng làm trọng tâm của cấu trúc Chữ ký web JSON (JWS) hoặc như hình thức văn bản thuần túy của cấu trúc Mã hóa Web JSON (JWE) (có thể hiểu là giá trị cốt lõi), cho phép sử dụng kỹ thuật số hoặc được bảo vệ toàn vẹn với Mã xác thực thư (MAC) mà có thể được mã hóa.
Thứ Tư, 30/09/2020 7257
|

Bài viết dựa trên tài liệu theo dõi tiêu chuẩn mở Internet. Đây là sản phẩm của nhóm chuyên viên kỹ thuật Internet (IETF) và hoành thành vào tháng 05 năm 2015. Những tác giả chính của tiêu chuẩn là M. Jones làm việc tại Microsoft, J. Bradley đến từ Ping indentity và N. Sakirumra đến từ NRI. Nó là sản phẩm thể hiện sự chung sức của cộng đồng IETF đồng thời nó đã nhận được đánh giá công khai và được phê duyệt đề xuất bản bởi khối chỉ đạo kỹ thuật Internet (IESG). Đây là tài liệu mở nhưng dễ hiểu và dễ sử dụng, đến nay JWT đã vô cùng phổ biến và được sử dụng rộng dãi trên toàn cầu. Đây là phiên bản duy nhất và vẫn được giữ được sự tin cậy cao trong các tiêu chuẩn mạng.

Hình 1: Mô phòng cho JWT

Nội dung chi tiết

1. Khái quát JSON Web Token

Như đã nói ở phần giới thiệu, JWT nhỏ gọn định nghĩa cách thức truyền tin an toàn giữa các thành viên bằng một đối tượng JSON. Thông tin này có thể xác thực và đánh dấu tin cậy nhờ vào “chữ ký” của nó. Phần chữ ký này được mã hóa lại bằng HMAC hoặc RSA.

Hình 2: Kết cấu của JWT

Header bao gồm hai phần chính: loại token và thuật toán đã dùng để mã hóa. Trong đó loại token có thể mặc định là JWT, một loại thông tin mà cho biết đoạn mã là một token JWT. Thuật toán có thể là HMAC SHA256 – HS256 hoặc RSA.

Payload chứa các “Claims”. Claims là một khối thông tin về một thực thể chẳng hạn người dùng là ai và một số metadata bắt buộc, số còn lại tuân theo về JWT hợp lệ và đầy đủ thông tin: iss (issuer), iat (issued-at time) exp (expiration time), sub (subject), aud (audience), … độ trễ phải hồi lại từ máy chủ khi tiếp nhận là do độ dài của Payload.

Singnature là chữ ký trong JWT hay một chuỗi đã được được mã hóa bởi header, payload cùng với một chuỗi bí mật theo nguyên tắc sau:

Hình 3 : Nguyên tắc của chuỗi chữ ký JWT

2. Cách thức hoạt động của JWT

Hình 4: Cách thức hoạt động của JWT

Như lượng đồ ở trên, chuỗi JWT được thực hiện theo một chu trình sau:

1. Người dùng (user) sử dụng trình duyệt đăng nhập vào một miền nào đó mà yêu cầu đăng nhập với tên đăng nhập và mật khẩu.

2. Máy chủ sẽ nhận được yêu cầu của người dùng, đồng thời kiểm tra thông tin tên đăng nhập và mật khẩu.

3. Máy chủ sau khi kiểm tra thông tin người dùng, nếu đúng sẽ trả một JWT về cho người dùng, nếu không quay lại bước 1.

4. Người dùng sẽ sử dụng mã JWT để tiếp tục sử dụng cho các yêu cầu kế tiếp trên miền của máy chủ.

5. Máy chủ sẽ không cần phải kiểm tra lại thông tin người dùng mà chỉ cần kiểm tra đúng JWT đã được cấp từ đó tăng tốc độ sử dụng trên miền giảm thời gian truy vấn.

6. Máy chủ trả phản hồi phù hợp cho người dùng.

Qua quá trình được nêu, rất rõ ràng JWT được tạo ra như một cách để trao đổi thông tin xác thực an toàn giữa hai bên. Vì vậy, JWT không ẩn, không làm mờ, không che giấu dữ liệu mà chỉ nhằm chức minh dữ liệu được tạo ra bởi một nguồn xác thực.

3. Tạo mã thông báo Web JSON

Để tạo một JWT, cần phải qua các bước sau, thứ tự của các bước không bắt buộc trong trường hợp không có sự phụ thuộc giữa đầu vào và đầu ra của các bước:

- Bước 1: Tạo bộ yêu cầu JWT chứa các giá trị Claim mong muốn. Lưu ý rằng biểu diễn khoảng trắng được cho phép tường minh mà không cần hợp thức hoá trước khi mã hoá.

- Bước 2: Đặt một tin nhắn là các octet của đại diện UTF-8 trong bộ Claim JWT.

- Bước 3: Tạo một Tiêu đề JOSE chứa bộ Thông số Header mong muốn. JWT PHẢI tuân thủ thông số kỹ thuật [JWS] hoặc [JWE]. Lưu ý rằng khoảng trắng được cho phép rõ ràng trong biểu diễn và không cần phải chuẩn hóa trước khi mã hóa.

- Bước 4: Tùy thuộc vào việc JWT là JWS hay JWE, có hai trường hợp:

+ Nếu JWT là JWS, hãy tạo JWS bằng Thông báo dưới dạng Tải trọng JWS; tất cả các bước được chỉ định trong [JWS] để tạo JWS PHẢI được tuân theo.

+ Khác, nếu JWT là JWE, hãy tạo JWE bằng cách sử dụng Tin nhắn làm văn bản gốc cho JWE; tất cả các bước được chỉ định trong [JWE] để tạo JWE PHẢI được tuân theo.

- Bước 5: Nếu thao tác ký hoặc mã hóa lồng nhau sẽ được thực hiện, hãy để Tin nhắn là JWS hoặc JWE và quay lại Bước 3, sử dụng giá trị "cty" (loại nội dung) của "JWT" trong JOSE header mới được tạo trong bước đó.

- Bước 6: Mặt khác, giá trị JWT kết quả là JWS hoặc JWE.

4. Xác thực JWT

Khi xác thực một JWT, các bước sau sẽ diễn ra, thứ tự của các bước không đáng kể trong trường hợp không có sự phụ thuộc giữa đầu vào và đầu ra của các bước. Nếu có bước nào được nêu dưới đây mà không thành thành công thì JWT PHẢI bị từ chối, hay bị ứng dụng đích coi là đầu vào không hợp lệ.

a. Xác thực rằng JWT chứa ít nhất một ký tự (‘.’).

b. Đoạn mã hóa JOSE Header phải được dặt ở vị trí trước ký tự (‘.’) đầu tiên của JWT.

c. Basse64 mã hóa JOSE header theo nguyên tắc là không có ngắt dòng, khoảng trắng hoặc các ký tự bổ sung khác đã được sử dụng.

d. Xác minh rằng chuỗi kết quả octet là một đại diện được mã hóa UTF-8 xủa một đối tượng JSON hoàn toàn hợp lệ tuân thủ RFC 7159 [RFC7159]; và để JOSE Header là một đối tượng JSON.

e. Xác minh rằng JOSE Header kết quả chỉ bao gồm các tham số, giá trị có cú pháp, ngữ nghĩa được hiểu và hỗ trợ hoặc được chỉ định là bị bỏ qua khi không hiểu.

f. Xác định xem JWT là JWS hay JWE bằng bất kỳ phương pháp khác thuộc JWE.

g. Tùy thuộc vào việc JWT là JWS hay JWE, có hai trường hợp:

- Nếu JWT là JWS, hãy làm theo các bước được chỉ định thuộc JWS để xác thực JWS. Đặt tin nhắn là kết quả của việc giải mã Base64url cho dữ liệu của JWS.

- Mặt khác, nếu JWT là JWE, hãy làm theo các bước được chỉ định trong JWE để xác thực JWE. Hãy để tin nhắn là bản mã JWE.

h. Nếu JOSE Header chứa giá trị "cty" (loại nội dung) của "JWT", thì Tin nhắn là JWT là chủ đề của các hoạt động ký hoặc mã hóa lồng nhau. Trong trường hợp này, quay lại Bước 1, sử dụng Tin nhắn làm JWT.

i. Mặt khác, base64url mã hóa tin nhắn theo hạn chế rằng không có ngắt dòng, khoảng trắng hoặc các ký tự bổ sung khác đã được sử dụng.

j. Xác minh rằng chuỗi kết quả octet là một đoạn mã UTF-8 đại diện cho một đối tượng JSON hoàn toàn hợp lệ tuân thủ RFC 7159 [RFC7159]; hãy để Bộ công bố JWT là đối tượng JSON này.

Cuối cùng, lưu ý rằng đây là một quyết định của ứng dụng mà thuật toán có thể được sử dụng trong ngữ cảnh cụ thể. Ngay cả khi JWT có thể được xác nhận thành công, trừ khi (các) thuật toán được sử dụng trong JWT được ứng dụng chấp nhận, nó vẫn có thể từ chối JWT.

5. Quy tắc so sánh chuỗi

Việc xử lý JWT chắc chắn đòi hỏi phải so sánh các chuỗi đã biết với các thành phần và giá trị nằm trong các JSON Object. Các quy tắc JSON để thực hiện so sánh tên thành phần được mô tả trong Định dạng trao đổi dữ liệu ký hiệu đối tượng JavaScript (JSON).

Các quy tắc so sánh này PHẢI được sử dụng cho tất cả các so sánh chuỗi JSON ngoại trừ trong trường hợp định nghĩa của thành phần gọi rõ ràng rằng quy tắc so sánh khác sẽ được sử dụng riêng cho giá trị thành phần đó. Và vì vậy, chỉ các giá trị thành viên "typ" và "cty" không sử dụng các quy tắc so sánh này.

Một số ứng dụng có thể bao gồm thông tin không phân biệt chữ hoa chữ thường trong giá trị phân biệt chữ hoa chữ thường, chẳng hạn như bao gồm tên DNS như một phần của giá trị khiếu nại "iss" (nhà phát hành). Trong các trường hợp đó, ứng dụng có thể cần xác định một quy ước cho trường hợp chính tắc được sử dụng để biểu diễn các phần không phân biệt chữ hoa chữ thường, chẳng hạn như yêu cầu viết thường, nếu nhiều bên có thể cần tạo ra cùng một giá trị thì mục đích để có thể so sánh chúng. (Tuy nhiên, nếu tất cả các bên sử dụng giá trị bên sản xuất đã phát hành mà không tham chiếu với giá trị độc lập nào khác thì giá trị được sử dụng bởi nhà sản xuất có thể không có ý nghĩa.)

6. Việc lưu trữ JWT trên máy chủ.

Trên thực tế, JWT được lưu trữ trên 2 cách chính đó là:

- HTML5 Web Storeage (localStorage hoặc sessionStorage)

- Cookies

Cả hai phương thức đều nhận JWT ở trình duyệt của người dùng, cả hai đều không lưu trạng thái vì tất cả các thông tin mà API cần là JWT. Cả hai phương thức đều gửi mã thông báo (token) lên Api một cách đơn giản nhưng điều khác biệt lớn nằm ở tính bảo mật.

Đối với bảo mật JWT lưu trữ trên sessionStroreage và localStoreage, máy chủ có thể truy cập được thông qua javaScript trên cùng domain. Hay nghĩa là bất cứ code javaScript nào chạy trên chính miền của máy chú đó có thể bị tấn công bằng XSS (một dạng lỗ hổng làm kẻ tấn công chèn được một đoạn code vào miền của máy chủ). Do đó phương pháp thông thường là loại bỏ và mã hóa tất cả các dữ liệu không tin tưởng được, tuy nhiên điều này là khó và không thể bảo mật toàn bộ.

Đối với bảo mật JWT lưu trữ trên cookie, thì khi được dùng cùng với cookie flag (HttpOnly) thì không thể bị truy cập bởi các đoạn code hay nhiễm XSS. Đồng thời có thể đặt cookie flag (đảm bảo chỉ trả JWT khi đi qua htttp đã được mã hóa hoặc xác thực) để đảm bảo rằng cookie chỉ được gửi qua HTTPS. Do đây việc lưu trữ JWT trên cookie là được khuyến nghị.

Một số trường hợp, nếu là trình duyệt web thì JWT có thể lưu vào localStoreage, Ứng dụng IOS thì sẽ là Keychain và ứng dụng Android thì sẽ lưu vào SharedPrefernces.

7. Khía cạnh bảo mật

Tất cả các vấn đề bảo mật liên quan đến bất kỳ ứng dụng mật mã nào phải được giải quyết bởi đồng thời giữa JWT với chữ ký Web JSON (JWS), mã hóa Web JSON (JWE) và phần mở ộng tệp (JWK). Trong số các vấn đề này là bảo vệ các khóa bí mật đối xứng và riêng tư bất đối xứng của người dùng và sử dụng các biện pháp đối phó với các cuộc tấn công khác nhau.

Tất cả các cân nhắc bảo mật trong đặc điểm kỹ thuật JWS cũng áp dụng cho JWT, cũng như các cân nhắc bảo mật JWE khi sử dụng mã hóa. Đặc biệt, Cân nhắc về bảo mật JWS JSON và Cân nhắc về bảo mật so sánh Unicode áp dụng như nhau đối với Bộ yêu cầu JWT theo cách tương tự như đối với Tiêu đề JOSE.

JWT có thể chứa các thông tin bí mật về quyền riêng tư của người dùng. Trong trường hợp này, PHẢI thực hiện các biện pháp để ngăn chặn việc tiết lộ thông tin này cho các bên ngoài ý muốn. Một cách để đạt được điều này là sử dụng JWT được mã hóa và xác thực người nhận, ứng dụng, máy chủ ứng dụng. Một cách khác là đảm bảo rằng các JWT chứa thông tin bí mật về quyền riêng tư không được mã hóa chỉ được truyền bằng các giao thức sử dụng mã hóa hỗ trợ xác thực điểm cuối, chẳng hạn như TLS (Transport layer security) - giao thức bảo mật tần giao vận. Bỏ qua thông tin nhạy cảm về quyền riêng tư khỏi JWT là cách đơn giản nhất để giảm thiểu các vấn đề về quyền riêng tư.

Ngoài yếu tố bảo mật về quyền riêng tư, JWT gần như tuyệt đối an toàn nằm xác thực ủy quyền.

Kết luận

JWT là một cơ chế xác thực vô cùng phổ biến và tuyệt vời. Nó cho phép người dùng khai báo thông tin người dùng và phạm vi truy cập của họ một cách có cấu trúc. Nó có thể được mã hóa và ký để chống giả mạo từ phía ứng dụng. Đồng thời việc hiểu rõ JWT cũng giúp việc nắm bắt một số tiêu chuẩn như tiêu chuẩn OpenID, OpenAPI, v.v một cách chính xác hơn, hiểu một cách rõ ràng và logic nhất.

Thông qua tiêu chuẩn mở này, ta có thêm các khía cạnh về bảo mật để xây dựng các nền tảng mới, đặc biệt nó là thành phần quan trọng trong tiêu chuẩn OpenID Connect 1.0. Nó cũng sẽ thành phần quan trọng để xây dựng khung chính phủ điện tử hướng tới xây dựng và phát triển chính phủ điện tử 2.0.

Vũ Cao Minh Đức

Tài liệu tham khảo

  1. https://viblo.asia/
  2. https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32
  3. Jones, M., "JSON Web Algorithms (JWA)",draft-ietf-jose-json-web-algorithms, December 2014.
  4. Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)",draft-ietf-jose-json-web-encryption, December 201
  5. Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", draft-ietf-jose-json-web-signature, December 2014.