Mã hoá

Mã hoá thường là một chủ đề nhằm bảo mật nhưng quyền riêng tư cũng rất quan trọng. Mục tiêu của mã hoá là ngăn người khác đọc thông tin đã mã hoá... nhưng việc ngăn người khác đọc thông tin của bạn là một cách để bảo mật thông tin. Người dùng thường bị giới hạn về khả năng tự thực hiện. Tuy nhiên, với sự hỗ trợ của bạn với tư cách là nhà cung cấp dịch vụ mà họ đang sử dụng, quá trình mã hoá có thể giúp giữ lại dữ liệu của họ.

Có 3 cách liên quan để áp dụng phương thức mã hoá nhằm hỗ trợ quyền riêng tư của người dùng: mã hoá trong quá trình truyền, mã hoá khi lưu trữ và mã hoá hai đầu:

  • Mã hoá trong quá trình truyền tải là quá trình mã hoá dữ liệu giữa người dùng và trang web của bạn, tức là HTTPS. Bạn có thể đã thiết lập HTTPS cho trang web của mình, nhưng bạn có chắc chắn tất cả dữ liệu truyền đến trang web của bạn đều được mã hoá không? Đây là mục đích của lệnh chuyển hướng và HSTS, được mô tả dưới đây và nên là một phần trong quá trình thiết lập HTTPS của bạn.
  • Mã hoá trong quá trình lưu trữ là quá trình mã hoá dữ liệu được lưu trữ trên máy chủ của bạn. Việc này giúp bảo vệ chống lại các sự cố rò rỉ dữ liệu và là một phần quan trọng trong quan điểm bảo mật của bạn.
  • Mã hoá hai đầu là việc mã hoá dữ liệu trên máy khách trước khi dữ liệu đó được gửi đến máy chủ của bạn. Việc này giúp bảo vệ dữ liệu người dùng ngay cả đối với bạn: bạn có thể lưu trữ dữ liệu của người dùng nhưng không thể đọc dữ liệu đó. Cách này khó triển khai và không phù hợp với mọi loại ứng dụng, nhưng là cách hỗ trợ hiệu quả cho quyền riêng tư của người dùng, vì không ai có thể xem dữ liệu của họ ngoài chính họ.

HTTPS

Bước đầu tiên là phân phối dịch vụ web của bạn qua HTTPS. Rất có thể bạn đã thực hiện việc này, nhưng nếu chưa thì đây là một bước quan trọng. HTTPS là HTTP, giao thức mà trình duyệt sử dụng để yêu cầu trang web từ máy chủ, nhưng được mã hoá bằng SSL. Điều này có nghĩa là kẻ tấn công bên ngoài không thể đọc hoặc can thiệp vào yêu cầu HTTPS giữa người gửi (người dùng của bạn) và người nhận (bạn), vì yêu cầu này được mã hoá nên họ không thể đọc hoặc thay đổi yêu cầu. Đây là quá trình mã hoá trong quá trình chuyển dữ liệu: trong khi dữ liệu di chuyển từ người dùng sang bạn hoặc từ bạn sang người dùng khác. Phương thức mã hoá HTTPS khi truyền cũng ngăn ISP của người dùng hoặc nhà cung cấp Wi-Fi mà họ đang sử dụng đọc được dữ liệu mà họ đang gửi cho bạn trong quá trình họ sử dụng dịch vụ của bạn. Điều này cũng có thể ảnh hưởng đến tính năng của dịch vụ: nhiều trường hợp sử dụng API JavaScript hiện tại yêu cầu trang web phải được phân phát qua HTTPS. MDN có danh sách đầy đủ hơn, nhưng các API được đặt cổng sau ngữ cảnh bảo mật bao gồm trình chạy dịch vụ, thông báo đẩy, chia sẻ web và tiền mã hoá web, cũng như một số API thiết bị.

Để phân phát trang web của bạn qua HTTPS, bạn cần có chứng chỉ SSL. Các tệp này có thể được tạo miễn phí thông qua Let's Encrypt hoặc thường do dịch vụ lưu trữ của bạn cung cấp nếu bạn đang sử dụng. Bạn cũng có thể sử dụng một dịch vụ của bên thứ ba để "tạo proxy" cho dịch vụ web của bạn và có thể cung cấp HTTPS, cũng như dịch vụ lưu vào bộ nhớ đệm và CDN. Có rất nhiều ví dụ về các dịch vụ như vậy, chẳng hạn như Cloudflare và Fastly — việc sử dụng chính xác dịch vụ nào phụ thuộc vào cơ sở hạ tầng hiện tại của bạn. Trước đây, HTTPS có thể tốn kém hoặc tốn kém khi triển khai. Đó là lý do HTTPS thường chỉ được dùng trên các trang thanh toán hoặc nguồn gốc đặc biệt bảo mật; nhưng các chứng chỉ được cung cấp miễn phí, những điểm cải tiến về tiêu chuẩn và sự gia tăng nhanh chóng của các trình duyệt đã loại bỏ được tất cả những trở ngại đó.

Nên

  • Bật HTTPS trên máy chủ của bạn cho mọi thứ (bất kể bạn chọn phương pháp nào).
  • Bạn nên dùng một proxy trước máy chủ của mình, chẳng hạn như Cloudflare (httpsiseasy.com/ giải thích quy trình này).
  • Let's Encrypt sẽ hướng dẫn bạn thực hiện quy trình tạo chứng chỉ SSL Let's Encrypt của riêng mình.
  • Bạn cũng có thể trực tiếp sử dụng OpenSSL để tạo chứng chỉ của riêng bạn và ký chứng chỉ đó bằng tổ chức phát hành chứng chỉ (CA) mà bạn chọn (Bật HTTPS giải thích chi tiết cách thực hiện).

Phương pháp bạn chọn phụ thuộc vào sự đánh đổi của hoạt động kinh doanh. Việc thiết lập kết nối SSL cho một bên thứ ba là cách dễ dàng nhất, ngoài ra còn đi kèm với các lợi ích khác như cân bằng tải, lưu vào bộ nhớ đệm và phân tích. Tuy nhiên, điều này cũng đi kèm với việc nhường lại một số quyền kiểm soát cho bên thứ ba đó và sự phụ thuộc không thể tránh khỏi các dịch vụ của họ (và việc thanh toán có thể có, tuỳ thuộc vào dịch vụ bạn sử dụng và mức lưu lượng truy cập của bạn).

Quy trình SSL trước đây thường tạo và có chữ ký của CA nhưng việc sử dụng Let's Encrypt có thể dễ dàng hơn nếu được nhà cung cấp của bạn hỗ trợ hoặc nếu nhóm máy chủ của bạn đủ thành thạo về mặt kỹ thuật và việc này lại miễn phí. Nhà cung cấp của bạn cũng thường cung cấp SSL dưới dạng dịch vụ nếu bạn đang sử dụng dịch vụ ở cấp cao hơn so với dịch vụ lưu trữ trên đám mây, vì vậy, bạn nên kiểm tra.

Tại sao nên

Bảo mật là một phần trong câu chuyện về quyền riêng tư của bạn: việc có thể chứng minh rằng bạn giữ an toàn cho dữ liệu người dùng khỏi sự can thiệp sẽ giúp tạo dựng lòng tin. Nếu bạn không sử dụng HTTPS, thì trang web của bạn cũng bị trình duyệt gắn cờ là "không an toàn" (và trong một thời gian dài). Các API JavaScript hiện tại thường chỉ được cung cấp cho các trang HTTPS ("nguồn gốc bảo mật"). Việc này cũng giúp bảo vệ người dùng khỏi việc nhà cung cấp dịch vụ Internet (ISP) sử dụng trang web của họ. Đây chắc chắn là một phương pháp hay nhất; không có lý do gì để không sử dụng HTTPS cho các trang web ngay bây giờ.

Cách trình duyệt trình bày một trang HTTP (không an toàn)

Cảnh báo URL "Không an toàn" trên máy tính của Chrome.
Google Chrome (máy tính)
Cảnh báo URL HTTP của Firefox.
Mozilla Firefox (máy tính)
Cảnh báo URL HTTP trên máy tính để bàn trong Safari.
Apple Safari (máy tính MacOS)
Cảnh báo HTTP trên thiết bị di động Android.
Google Chrome (thiết bị di động Android)
Cảnh báo HTTP trên iOS của Apple Safari.
Apple Safari (thiết bị di động iOS)

Chuyển hướng đến HTTPS

Nếu trang web của bạn có trên cả hai URL http: và https:, bạn nên chuyển hướng tất cả các URL http đến https. Điều này là vì những lý do nêu trên và cũng đảm bảo rằng trang web của bạn sẽ không xuất hiện trên whynohttps.com nếu trang web đó trở nên phổ biến. Cách thực hiện việc này phụ thuộc rất nhiều vào cơ sở hạ tầng của bạn. Nếu được lưu trữ trên AWS, bạn có thể dùng trình cân bằng tải hoặc Ứng dụng. Google Cloud cũng tương tự như vậy. Trong Azure, bạn có thể tạo Cửa trước; trong Nút có Express, hãy kiểm tra request.secure; trong Nginx bắt tất cả cổng 80 và trả về 301; và trong Apache, hãy sử dụng RewriteRule. Nếu bạn đang sử dụng một dịch vụ lưu trữ, có nhiều khả năng là các dịch vụ đó sẽ tự động xử lý việc chuyển hướng đến các URL HTTPS cho bạn: Netlify, Firebase và GitHub Pages, cùng nhiều dịch vụ khác.

Bảo mật truyền tải nghiêm ngặt HTTPS (HSTS)

HSTS là viết tắt của "HTTP Strict-Transport-Security" và là một cách để khóa trình duyệt sử dụng HTTPS cho dịch vụ của bạn mãi mãi. Khi đã hài lòng với quá trình di chuyển sang HTTPS hoặc nếu đã làm việc đó, bạn có thể thêm tiêu đề phản hồi HTTP Strict-Transport-Security vào các phản hồi gửi đi. Một trình duyệt từng truy cập vào trang web của bạn sẽ ghi lại việc đã xem tiêu đề này. Kể từ đó, trình duyệt sẽ tự động truy cập vào trang web này dưới dạng HTTPS ngay cả khi bạn yêu cầu HTTP. Điều này giúp bạn tránh việc chuyển hướng như ở trên: giống như trình duyệt đang ngầm "nâng cấp" tất cả các yêu cầu lên dịch vụ của bạn để sử dụng HTTPS.

Tương tự, bạn có thể phân phát tiêu đề Upgrade-Insecure-Requests cùng với các trang của mình. Thao tác này hoạt động khác với nhưng liên quan đến Strict-Transport-Security. Nếu bạn thêm Upgrade-Insecure-Requests: 1, thì các yêu cầu từ trang này đến các tài nguyên khác (hình ảnh, tập lệnh) sẽ được yêu cầu dưới dạng https ngay cả khi liên kết là http. Tuy nhiên, trình duyệt sẽ không tự yêu cầu lại trang đó dưới dạng https và trình duyệt sẽ không ghi nhớ trang đó cho lần tiếp theo. Trên thực tế, Yêu cầu nâng cấp không an toàn sẽ hữu ích nếu bạn chuyển đổi một trang web hiện có có nhiều đường liên kết sang HTTPS và việc chuyển đổi URL liên kết trong nội dung là một việc khó khăn, nhưng bạn nên thay đổi nội dung nếu có thể.

HSTS chính là một tính năng bảo mật: nó "khoá" trang web của bạn với HTTPS đối với những người dùng đã từng sử dụng giao thức này trước đó. Tuy nhiên, như trên, HTTPS phù hợp với quyền riêng tư, còn HSTS phù hợp với HTTPS. Tương tự, yêu cầu nâng cấp không thực sự cần thiết nếu bạn đang cập nhật tất cả nội dung của mình. Tuy nhiên, đây là một phương pháp "hỗ trợ" hữu ích để tăng cường khả năng phòng vệ chuyên sâu nhằm đảm bảo trang web của bạn sẽ luôn là HTTPS.

Nên

Thêm tiêu đề HSTS vào thư trả lời đi:

Strict-Transport-Security: max-age=300; includeSubDomains

Thông số max-age cho biết khoảng thời gian (tính bằng giây) mà trình duyệt cần ghi nhớ và thực thi quá trình nâng cấp HTTPS. (Ở đây, chúng ta đặt thành 300 giây, tức là năm phút.) Cuối cùng, bạn muốn giá trị này là 6.3072.000, tức là hai năm và là con số mà hstspreload.org đề xuất, nhưng sẽ rất khó để khôi phục nếu có vấn đề. Vì vậy, bạn nên đặt chỉ số này với một con số thấp lúc đầu (300), kiểm thử để xác nhận không có vấn đề nào, sau đó tăng số lượng theo từng giai đoạn.

Thêm tiêu đề Upgrade-Insecure-Requests vào thư trả lời gửi đi:

Upgrade-Insecure-Requests: 1 Content-Security-Policy: upgrade-insecure-requests

Mã hoá hai đầu

Một cách hay để đảm bảo tính riêng tư cho dữ liệu người dùng là không hiển thị dữ liệu đó cho bất kỳ ai khác ngoài người dùng đó, kể cả bạn. Điều này giúp ích rất nhiều cho sự tin tưởng của bạn: nếu bạn không có dữ liệu của người dùng thì rõ ràng là bạn không thể làm gì với dữ liệu đó mà họ không muốn. Một cách để thực hiện việc này là không để dữ liệu người dùng rời khỏi thiết bị của họ, bằng cách lưu trữ mọi thứ ở phía máy khách. Phương pháp này hiệu quả, nhưng có một số hạn chế đối với một ứng dụng thuần tuý phía máy khách: bộ nhớ dữ liệu của trình duyệt có thể bị giới hạn về dung lượng và trong một số trình duyệt có thể bị xoá mà có rất ít hoặc không có cảnh báo. Bạn cũng khó hoặc không thể truy cập vào dữ liệu của mình trên hai thiết bị, chẳng hạn như máy tính xách tay và điện thoại di động. Vì lý do này, bạn nên gửi dữ liệu đến máy chủ như bình thường, nhưng mã hoá dữ liệu đó bằng một khoá mà chỉ người dùng biết để máy chủ không thể truy cập (vì máy chủ không thể giải mã) nhưng có thể lưu trữ dữ liệu đó.

Cách thức hoạt động

Phương pháp này thường được các ứng dụng nhắn tin sử dụng, còn gọi là "mã hoá hai đầu" hoặc "e2e". Bằng cách này, 2 người biết khoá của nhau có thể mã hoá và giải mã tin nhắn qua lại rồi gửi các tin nhắn đó qua nhà cung cấp dịch vụ nhắn tin, nhưng nhà cung cấp dịch vụ nhắn tin (không có các khoá đó) không thể đọc được tin nhắn. Hầu hết ứng dụng không phải là ứng dụng nhắn tin, nhưng bạn có thể kết hợp 2 phương pháp – chỉ một kho dữ liệu phía máy khách và mã hoá dữ liệu bằng một khoá mà ứng dụng đã biết – để lưu trữ dữ liệu trên máy, đồng thời gửi dữ liệu đó đã được mã hoá đến máy chủ. Điều quan trọng là bạn phải nhận ra rằng có các hạn chế trong phương pháp này: điều này không áp dụng được cho tất cả các dịch vụ và cụ thể là không thể sử dụng phương pháp này nếu bạn, với tư cách là nhà cung cấp dịch vụ, cần có quyền truy cập vào nội dung mà người dùng đang lưu trữ. Như đã mô tả trong phần 2 của loạt bài viết này, tốt nhất bạn nên tuân theo nguyên tắc giảm tối đa việc thu thập dữ liệu; tránh thu thập dữ liệu trong mọi trường hợp nếu có thể. Nếu người dùng cần lưu trữ dữ liệu nhưng bạn không cần quyền truy cập vào dữ liệu đó để cung cấp dịch vụ, thì phương thức mã hoá hai đầu sẽ hữu ích. Nếu bạn cung cấp những dịch vụ yêu cầu bạn phải xem được những gì người dùng lưu trữ để cung cấp dịch vụ, thì phương thức mã hoá hai đầu sẽ không phù hợp. Nhưng nếu không, bạn có thể yêu cầu JavaScript phía máy khách của dịch vụ web mã hoá mọi dữ liệu mà dịch vụ này gửi đến máy chủ và giải mã mọi dữ liệu nhận được.

Ví dụ: Excalidraw

Excalidraw thực hiện việc này và giải thích cách thực hiện trong một bài đăng trên blog. Đây là một ứng dụng vẽ vectơ lưu trữ các bản vẽ trên máy chủ, được mã hoá bằng một khoá được chọn ngẫu nhiên. Một phần lý do khiến Excalidraw có thể triển khai phương thức mã hoá hai đầu này mà chỉ cần tương đối ít mã là các thư viện mật mã hiện được tích hợp vào trình duyệt bằng window.crypto. Đây là một tập hợp các API JavaScript được hỗ trợ trong tất cả các trình duyệt hiện đại. Việc mã hoá rất khó và việc triển khai các thuật toán cũng đi kèm với nhiều trường hợp hiếm gặp. Việc trình duyệt thực hiện phần việc nặng nhọc ở đây sẽ giúp các nhà phát triển web dễ dàng truy cập vào quá trình mã hoá, từ đó giúp việc triển khai quyền riêng tư qua dữ liệu được mã hoá trở nên dễ dàng hơn. Như Excalidraw mô tả trong bản ghi, khoá mã hoá vẫn nằm ở phía máy khách vì nó thuộc phân đoạn URL: khi trình duyệt truy cập URL https://example.com/path?param=1#fraghere, đường dẫn của URL (/path) và tham số (param=1) sẽ được chuyển đến máy chủ (example.com), nhưng phân đoạn (fraghere) thì không, nên máy chủ không bao giờ nhìn thấy nó. Điều này có nghĩa là ngay cả khi dữ liệu đã mã hoá truyền qua máy chủ, thì khoá mã hoá sẽ không bảo vệ. Do đó, quyền riêng tư vẫn được bảo vệ vì dữ liệu được mã hoá hai đầu.

Các điểm hạn chế

Phương pháp mã hoá dữ liệu người dùng này không phải lúc nào cũng hiệu quả. Điều này góp phần tạo nên lập trường tin cậy của bạn đối với người dùng nhưng không thể thay thế hoàn toàn. Người dùng sẽ vẫn phải tin tưởng dịch vụ của bạn, vì bất cứ lúc nào bạn cũng có thể hoán đổi dữ liệu phía máy khách của một nhà cung cấp dịch vụ với một số JavaScript tương tự, không mã hoá dữ liệu một cách đáng tin cậy; và mặc dù người dùng có thể phát hiện liệu trang web bạn đang sử dụng có làm được điều đó hay không

Bạn cũng cần nhớ rằng một trong những mục tiêu của phương thức mã hoá hai đầu là ngăn bạn, chủ sở hữu trang web, đọc được dữ liệu. Điều này rất tốt cho quyền riêng tư, nhưng cũng có nghĩa là nếu xảy ra sự cố, bạn không thể trợ giúp. Về cơ bản, một dịch vụ sử dụng phương thức mã hoá hai đầu sẽ cho phép người dùng chịu trách nhiệm về các khoá mã hoá. (Điều này có thể không rõ ràng hoặc công khai, nhưng ai đó phải có khoá và nếu dữ liệu được giữ riêng tư với bạn, thì đó không phải là bạn.) Nếu các khoá đó bị mất, thì bạn sẽ không thể làm gì để trợ giúp và có thể mọi dữ liệu được mã hoá bằng các khoá đó cũng có thể bị mất. Ở đây, có một hoạt động cân bằng hợp lý giữa quyền riêng tư và khả năng hữu dụng: giữ cho dữ liệu ở chế độ riêng tư với bất kỳ ai sử dụng phương thức mã hoá, nhưng cũng tránh buộc người dùng phải trở thành chuyên gia về mật mã học để quản lý khoá của riêng họ một cách bảo mật.

Mã hoá ở trạng thái tĩnh

Bên cạnh việc mã hoá dữ liệu của người dùng trong quá trình chuyển dữ liệu, bạn cũng cần cân nhắc việc mã hoá dữ liệu mà bạn đã lưu trữ trên máy chủ. Điều này giúp ngăn chặn các sự cố rò rỉ dữ liệu, vì bất kỳ ai truy cập trái phép vào dữ liệu đã lưu trữ của bạn đều sẽ có dữ liệu đã mã hoá. Họ hy vọng rằng họ sẽ không có khoá để giải mã. Có 2 phương pháp bổ sung và khác nhau để mã hoá dữ liệu tĩnh: mã hoá bạn thêm và lớp mã hoá do nhà cung cấp bộ nhớ trên đám mây thêm vào (nếu bạn đang sử dụng một nhà cung cấp bộ nhớ trên đám mây). Phương thức mã hoá của nhà cung cấp bộ nhớ không cung cấp nhiều biện pháp bảo vệ chống lại các sự cố rò rỉ dữ liệu thông qua phần mềm của bạn (vì quá trình mã hoá của nhà cung cấp bộ nhớ thường minh bạch đối với bạn với tư cách là người dùng dịch vụ của họ), nhưng điều này giúp chống lại các sự cố rò rỉ dữ liệu xảy ra tại cơ sở hạ tầng của nhà cung cấp. Việc bật tính năng này thường rất đơn giản nên bạn nên cân nhắc sử dụng. Trường này thay đổi nhanh chóng và đội ngũ bảo mật của bạn (hoặc các kỹ sư có kiến thức về bảo mật trong nhóm của bạn) là gợi ý phù hợp nhất về vấn đề này. Tuy nhiên, tất cả các nhà cung cấp bộ nhớ trên đám mây đều cung cấp tính năng mã hoá ở trạng thái tĩnh cho bộ nhớ khối Amazon S3 bằng cách cài đặt, Azure StorageGoogle Cloud Storage theo mặc định, cũng như cho việc lưu trữ dữ liệu cơ sở dữ liệu AWS RDS, Azure SQL, Google Cloud Hãy kiểm tra điều này với nhà cung cấp bộ nhớ trên đám mây của bạn nếu bạn đang sử dụng một nhà cung cấp. Việc tự xử lý việc mã hoá dữ liệu ở trạng thái tĩnh để giúp bảo vệ dữ liệu người dùng khỏi các sự cố rò rỉ dữ liệu sẽ khó khăn hơn vì việc quản lý an toàn khoá mã hoá và cung cấp khoá mã hoá để mã hoá mà không cung cấp khoá cho kẻ tấn công cũng khó khăn. Đây không phải là nơi tốt nhất để tư vấn về các vấn đề bảo mật ở cấp độ đó; hãy trao đổi với các kỹ sư có kiến thức về bảo mật hoặc nhóm chuyên trách về vấn đề này hoặc với các cơ quan bảo mật bên ngoài.