Uint8array nodejs
Đã từ lâu, Javascript ra đời giúp các nhà phát triển có thể xây dựng các trang web với nhiều logic phức tạp, thực hiện đủ thứ xử lý ở phía máy khách ngay, không cần nhờ máy chủ. Tuy nhiên, số lượng các thư viện Javascript cung cấp tính năng mã hóa/giải mã khá hạn chế và cũng dẫn đến các ứng dụng web cung cấp khả năng mã hóa nội dung ngay trên trình duyệt không phổ biến. Ít nhất là cho đến thời gian gần đây, với sự xuất hiện của Web Crypto API Show
Đặc tính, tính đơn luồng, bất đồng bộ và hiệu năng thấp (so với các ngôn ngữ như C, Rust), tất cả đều làm cho Javascript không phù hợp với các thuật toán liên quan đến mã hóa/giải mã. Bản thân Javascript cũng thiếu tính năng tạo dữ liệu giả ngẫu nhiên đủ an toàn (CSPRNG, hay viết tắt của trình tạo số giả ngẫu nhiên bảo mật bằng mật mã). Vì vậy, Web Crypto API ra đời nhằm cung cấp các tính năng mã hóa/giải mã an toàn ngay trên trình duyệt Tại sao cần WebCrypto API?Trong thế giới web, người dùng thường phải "tin tưởng máy chủ". Người dùng nhập mật khẩu đăng ký tài khoản, khả năng đó cũng là mật khẩu chúng ta sử dụng cho email và nhiều tài khoản trên mạng khác (vì chắc nhớ nhiều mà), và sau đó phải hy vọng máy chủ của trang web sẽ bảo vệ mật khẩu đủ mức . Người dùng cũng phải mong muốn các nội dung khác bạn lưu vào máy chủ sau đó như hộp thư đến, số thẻ tín dụng,. được bảo mật và không có vụ rò rỉ dữ liệu nào xảy ra Gần đây quyền riêng tư đang là vấn đề nóng. Nhiều trang web ngày càng sử dụng dữ liệu của người dùng nhiều hơn cho mục đích riêng. Gmail sử dụng email nội dung phục vụ cho quảng cáo được cá nhân hóa, hay Evernote tuyên bố sẽ cho nhân viên đọc các đoạn trích ngắn trong ghi chú của người dùng để phục vụ cho máy học. Chưa kể, nếu chủ nhân trang web tuyên bố sẽ tôn trọng quyền riêng tư của người dùng, thì trường hợp éo le như chủ web đó bị đe dọa hay chính phủ yêu cầu, dữ liệu người dùng vẫn bị xâm phạm như thường, tiêu Vì những lý do trên, nhiều người đã muốn tạo các ứng dụng Web theo kiểu Zero-Knowledge hoặc có khả năng mã hóa phía client (mã hóa phía máy khách) hoặc mã hóa đầu cuối (mã hóa đầu cuối). Máy chủ phía sau của các ứng dụng Web này chỉ được sử dụng để lưu hoặc truyền tải dữ liệu đã được mã hóa. Key giải mã không bao giờ được gửi đến máy chủ và quá trình mã hóa/giải mã được thực hiện hoàn toàn ngoại tuyến ở phía máy khách. Như vậy các máy chủ này hoàn toàn không có kiến thức. Một số trang Web tiên phong theo mô hình này điển hình như bitwarden. com, ghi chú chuẩn. org hay protonmail. com. Cá biệt có dịch vụ web tận dụng mã hóa phía máy khách để bảo vệ máy chủ chính của họ khỏi những vấn đề liên quan đến luật, ví dụ như trang tải lên tệp có mã hóa phía máy khách lớn. nz Nhưng nên nhớ, dù thế nào đi chăng nữa, bạn vẫn phải tin tưởng vào máy chủ, ít nhất là để cung cấp cho bạn các đoạn mã phía máy khách (như javascript) một cách an toàn. Chỉ có điều máy chủ không cần biết quá nhiều Cách sử dụngDưới đây mình chỉ hướng dẫn cách sử dụng cơ bản cho mục đích giới thiệu và rất có thể nhiều chỗ không chính xác và không an toàn. Nên nhớ rằng nếu bạn muốn làm một trang Web tận dụng Web Crypto API với yêu cầu bảo mật cao, bạn phải cẩn thận hơn là rất nhiều, và có đủ hiểu biết về một thông tin đầy đủ. Một sai lầm nhỏ sẽ khiến việc mã hóa trở nên mất hiệu quả hoặc hoàn toàn vô hiệu Để hiểu bài viết rõ ràng nhất, bạn cần biết một chút về javascript như lời hứa và async/await, các kiến thức về 8 và các góc nhìn của nó 9. Ngoài ra, để giảm thiểu thời gian, các ví dụ trong bài được thực hiện bởi thư viện Vue. jsNgoài ra, vì công nghệ Web luôn thay đổi rất nhanh, để có những thông tin chính xác nhất, bạn nên tham khảo tài liệu của MDN về Web Crypto API Sinh ngẫu nhiên với const getKeyMaterial = async (passwordString) => { const passwordBuffer = new TextEncoder().encode(passwordString); return await crypto.subtle.importKey("raw", passwordBuffer, "PBKDF2", false, ["deriveBits"]); } 0Giúp tạo dữ liệu giả ngẫu nhiên đủ an toàn để sử dụng với mã hóa (CSPRNG). Thường được dùng để tạo ra IV, muối,
Nhớ rằng máy tính của chúng ta là. máy tính, nó không hề có khái niệm ngẫu nhiên. Hàm ngẫu nhiên của các ngôn ngữ lập trình chỉ tạo ra dữ liệu "trông có vẻ" ngẫu nhiên bằng cách phụ thuộc vào trạng thái bên trong bất kỳ trạng thái nào, nên được gọi là giả ngẫu nhiên. Hàm ngẫu nhiên bình thường này (PRNG) cho hiệu năng cao nhưng dễ đoán các giá trị ngẫu nhiên tiếp theo, nên chỉ phù hợp với mục đích của hệ thống kê CSPRNG only other PRNG at two point
Điều đó khiến cho CSPRNG đủ an toàn cho các mục đích mã hóa hash by const getKeyMaterial = async (passwordString) => { const passwordBuffer = new TextEncoder().encode(passwordString); return await crypto.subtle.importKey("raw", passwordBuffer, "PBKDF2", false, ["deriveBits"]); } 1Trợ giúp "băm" hay băm bất kỳ dữ liệu nào bằng một loại hàm băm nhanh. Show it only support. SHA-1, SHA-256, SHA-384, SHA-512
Lưu ý rằng, sử dụng hàm băm nhanh để xác thực tính toàn vẹn của dữ liệu. Don't bao giờ sử dụng hàm hash nhanh như ở trên để bảo vệ hoặc tạo khóa cho mật khẩu Băm mật khẩu với PBKDF2PBKDF2 là hàm giúp sinh khóa từ mật khẩu một cách an toàn (hàm dẫn xuất khóa). Khóa này có thể được sử dụng để làm khóa trong thuật toán mã hóa (như AES) Tuy mục đích ban đầu của PBKDF2 là tạo khóa, PBKDF2 cũng được coi là đủ cả ngày để tạo mật khẩu băm hay mật khẩu tiêu hóa (băm mật khẩu). PBKDF2 được thiết kế để làm chậm, điều này giúp tấn công brute force để tìm khóa được sinh ra qua hàm PBKDF2 khó hơn rất nhiều Tạo hàm băm cho mật khẩu với PBKDF2 cần có các yếu tố sau
Chúng ta sẽ sử dụng 43 để tạo mã mũ trùm đầu, nhưng có một số công việc phải làm trướcChuyển chuỗi mật khẩu cần tạo mã băm sang dạng đối tượng const digest = crypto.subtle.digest(algorithm, data); 44 43 hơi phiền là không chấp nhận mật khẩu dưới dạng chuỗi thông thường, chỉ chấp nhận nhận mật khẩu ở dạng đối tượng 44. Do đó ta phải chuyển đổi mật khẩu định danh thành một đối tượng 44 trước bằng 48. Nhưng lại tiếp tục, yêu cầu mật khẩu 48 phải ở dạng 8 ( Túm lại là như sau.
tạo muốiUse 0 as at on section 4Tiến hành tạo mã hashSau khi đã có 2 thành phần trên, chúng ta tiến hành tạo mã băm qua 43 9ReconnectionGắn kết 3 hàm trên lại với nhau 0Hãy nhớ rằng 93 sẽ trả về một 94 mà sau một khoảng thời gian sẽ trả về một 8 chứa kết quả bẩnBạn nên tham khảo ví dụ bên dưới để hiểu rõ, đồng thời có thể tham khảo thêm tại https. //Trung bình. com/coinmonks/fun-times-with-webcrypto-part-1-pbkdf2-815b1c978c9d Như đã nói ở trên, PBKDF2 cũng được sử dụng để tạo ra khóa từ mật khẩu cho thuật toán như AES. Phần dưới đây sẽ đi vào chi tiết hơn Mã hóa đối xứng (và giải mã) với AES-GCMHiểu ngắn gọn, mã hóa đối xứng là kiểu mã hóa mà bạn sử dụng cùng một khóa (phím) để mã hóa và giải mã dữ liệu. Còn AES là thuật toán mã hóa đối với rất an toàn và mạnh mẽ hiện nay, kể cả cho mục tiêu chính phủ hay quân sự AES thường sử dụng key với độ dài 256 bit. Nói đơn giản thì không ai có thể tấn công vét cạn (brute force) đoạn khóa này với công nghệ hiện tại. Để tạo đoạn khóa dài 256 bit dành cho AES, người ta có thể chọn sử dụng CSPRNG để sinh ra đoạn khóa bất kỳ, hoặc sinh khóa từ mật khẩu với một hàm sinh khóa (hàm dẫn xuất khóa) như PBKDF2 AES-GCM là kiểu thuật toán AES thông dụng nhất, cho hiệu năng giải mã tốt hơn với CPU đa nhân, đồng thời đảm bảo tính xác thực của dữ liệu, tức thì biết dữ liệu còn nguyên trạng khi giải mã hay không Để tránh việc sử dụng cùng một khóa mã hóa ra các dữ liệu giống nhau cho các dữ liệu đã mã hóa giống nhau, người ta sử dụng thêm một giá trị gọi là IV (Vectơ khởi tạo). IV là đoạn giá trị độc nhất (ngẫu nhiên thì càng tốt) khá giống muối. Ngoài ra đặc biệt với AES-GCM, sử dụng IV/nonce độc nhất cho mỗi lần mã hóa là bắt buộc và vô cùng quan trọng, tốt nhất là trong trường hợp bạn sử dụng cùng một phím để mã hóa nhiều dữ liệu khác nhau. Trong bài viết này mình xin tạm thời chọn độ dài giá trị IV/nonce là 12 byte (96 bit) Dưới đây mình sẽ chọn mã hóa bằng cách sinh khóa từ mật khẩu, đồng thời dữ liệu được chọn để mã hóa chỉ là đoạn chữ UTF-8 Create key from passwordSử dụng PBKDF2. Gần giống như mái che với phần băm mật khẩu bằng PBKDF2 ở phía trên, chỉ khác một chút ở nơi sử dụng 96 thay cho 43 |