tools / rsa
rsa/
Mã hóa bằng khóa công khai RSA và giải mã bằng khóa riêng, hoặc mã hóa bằng khóa riêng và giải mã bằng khóa công khai. Padding, định dạng khóa, định dạng đầu vào / đầu ra và bộ ký tự đều chọn được, khóa không rời khỏi trình duyệt.
Bản rõ
Khóa
Bản mã
Lịch sử
Mỗi lần mã hóa hoặc giải mã thành công sẽ tự động ghi lại một mục, giữ 20 mục gần nhất và chỉ lưu trong trình duyệt của thiết bị này. Khóa không được lưu, nhưng bản rõ sau khi giải mã thì có, nên hãy xóa lịch sử sau khi dùng trên máy tính dùng chung.
AES, DES và RSA là gì, khác nhau thế nào
AES và DES là mã hóa đối xứng: mã hóa và giải mã dùng chung một khóa, giống như một chiếc chìa vừa khóa cửa vừa mở cửa. Chúng chạy nhanh, phù hợp để mã hóa lượng dữ liệu lớn; khó khăn nằm ở chỗ làm sao gửi khóa này cho đối phương một cách an toàn.
DES là chuẩn cũ từ thập niên 1970, khóa hiệu dụng chỉ có 56 bit, ngày nay phần cứng chuyên dụng hoặc cụm máy tính có thể dò vét cạn để phá, nên chỉ dùng khi cần kết nối với những hệ thống cũ vẫn còn dùng nó. AES là chuẩn mới thay thế DES, khóa 128, 192 hoặc 256 bit, hiện chưa có cách phá khả thi và là lựa chọn hàng đầu để mã hóa dữ liệu.
RSA là mã hóa bất đối xứng: có một cặp khóa. Khóa công khai có thể đưa cho bất kỳ ai và dùng để mã hóa; khóa riêng do bạn tự giữ và dùng để giải mã. Giống như một hòm thư ai cũng bỏ thư vào được nhưng chỉ bạn có chìa để mở. Ưu điểm là không cần thống nhất khóa từ trước, nhược điểm là rất chậm và mỗi lần chỉ mã hóa được vài trăm byte. Hệ thống thực tế thường kết hợp cả hai: dùng RSA mã hóa một khóa AES sinh ngẫu nhiên rồi gửi cho đối phương, sau đó dùng AES mã hóa dữ liệu thật.
Mỗi lần mã hóa được bao nhiêu nội dung
RSA mỗi lần chỉ mã hóa được một đoạn dữ liệu nhỏ, giới hạn do độ dài khóa và kiểu padding quyết định. Với PKCS1Padding, tối đa là số byte của khóa trừ 11, khóa 2048 bit là 245 byte; với OAEP, tối đa là số byte của khóa trừ hai lần độ dài hash rồi trừ 2, khóa 2048 bit dùng SHA-256 là 190 byte. Dữ liệu dài hơn thường được mã hóa bằng AES trước, rồi dùng RSA để mã hóa khóa AES.
Đối chiếu với cách viết trong Java
Tên kiểu padding khớp với Cipher của Java: RSA/ECB/PKCS1Padding thì chọn PKCS1Padding; RSA/ECB/OAEPWithSHA-256AndMGF1Padding thì chọn mục thứ ba, vì Java mặc định dùng SHA-1 cho MGF1; khi tùy chỉnh hash bằng OAEPParameterSpec thì chọn OAEPPadding, rồi chọn riêng OAEP hash và MGF1 hash. Bộ ký tự cũng theo quy tắc của Java, ví dụ mã hóa UTF-16 sẽ có FE FF ở đầu và xếp theo big-endian.
Vì sao mỗi lần mã hóa cho kết quả khác nhau
Khi mã hóa bằng khóa công khai, cả PKCS1Padding và OAEP đều thêm byte ngẫu nhiên vào phần padding, nên cùng một nội dung mỗi lần mã hóa cho ra bản mã khác nhau, nhưng tất cả đều giải mã được bằng khóa riêng; đây là hiện tượng bình thường. Mã hóa bằng khóa riêng dùng padding cố định nên kết quả lần nào cũng giống nhau. OAEP chỉ dùng được cho mã hóa bằng khóa công khai và giải mã bằng khóa riêng.
Hỗ trợ những khóa nào
PEM hỗ trợ bốn dạng BEGIN PUBLIC KEY, BEGIN RSA PUBLIC KEY, BEGIN PRIVATE KEY, BEGIN RSA PRIVATE KEY, cũng có thể chỉ dán phần Base64 ở giữa; hex là cùng nội dung đó ở dạng thập lục phân. Khóa riêng có mật khẩu cần được giải mã trước. Khi loại khóa là khóa công khai, bạn cũng có thể dán thẳng khóa riêng, phần khóa công khai trong đó sẽ được dùng.
Câu hỏi thường gặp
Làm gì khi giải mã báo "khóa không khớp cặp, loại khóa hoặc kiểu padding sai"
Kiểm tra lần lượt ba điểm: một là khóa có đúng là cặp với khóa công khai đã dùng để mã hóa không, nội dung mã hóa bằng khóa công khai chỉ giải mã được bằng khóa riêng tương ứng; hai là loại khóa phải chọn khóa riêng; ba là kiểu padding phải khớp với bên mã hóa. Khi chọn OAEPPadding, OAEP hash và MGF1 hash cũng phải giống bên mã hóa. Cuối cùng xác nhận định dạng đầu vào không bị chọn sai, chọn nhầm giữa hex và base64 cũng khiến giải mã thất bại.
Làm gì khi báo định dạng khóa không đúng, hoặc "Không hỗ trợ CERTIFICATE"
Trước hết xác nhận "Định dạng khóa" khớp với nội dung đã dán: bắt đầu bằng -----BEGIN thì chọn pem, một chuỗi thập lục phân dài thì chọn hex; khi chọn sai thường sẽ có thông báo cho biết nên đổi sang cái nào. Trong PEM phải là khóa công khai hoặc khóa riêng RSA, chứng chỉ (BEGIN CERTIFICATE) không dùng trực tiếp được, bạn có thể trích khóa công khai trước bằng openssl x509 -in cert.pem -pubkey -noout. Khi chứng chỉ và khóa được dán chung, khối khóa sẽ tự động được chọn ra.
Khóa riêng có mật khẩu, báo "hãy giải mã thành khóa riêng không có mật khẩu" thì phải làm sao
Khóa riêng có mật khẩu không được hỗ trợ (BEGIN ENCRYPTED PRIVATE KEY, hoặc dòng Proc-Type: 4,ENCRYPTED trong phần đầu PEM), cần bỏ mật khẩu trên máy của bạn trước rồi mới dán, ví dụ dùng openssl rsa -in original-file -out new-file, nhập mật khẩu khi được hỏi. Tệp sau khi bỏ mật khẩu chính là khóa riêng dạng bản rõ, dùng xong hãy xử lý cẩn thận.
Báo nội dung vượt quá giới hạn thì mã hóa được bao nhiêu chữ Hán
Giới hạn tính theo byte, không phải theo số ký tự. Khóa 2048 bit với PKCS1Padding tối đa 245 byte, một chữ Hán chiếm 3 byte trong UTF-8 nên được khoảng 81 chữ; khi chọn bộ ký tự GBK, một chữ Hán chiếm 2 byte, được khoảng 122 chữ. Khi mã hóa, sau khi dán khóa, bên cạnh tiêu đề ô khóa sẽ hiện "Mỗi lần mã hóa tối đa N byte" theo khóa và kiểu padding hiện tại. Vượt giới hạn sẽ báo lỗi ngay, công cụ này không tự chia đoạn để mã hóa.
Kết quả mã hóa bằng JSEncrypt hoặc Web Crypto ở front-end thì giải mã ở đây thế nào
JSEncrypt dùng PKCS1Padding và xuất ra Base64, nên ở đây chọn padding là PKCS1Padding, định dạng đầu vào là base64. RSA-OAEP của Web Crypto trong trình duyệt dùng cùng một hash cho cả OAEP và MGF1, nên ở đây phải chọn OAEPPadding và đặt OAEP hash và MGF1 hash cùng một giá trị, ví dụ cùng chọn SHA256. Cả hai trường hợp đều chọn loại khóa là khóa riêng.
Thông báo bản mã "dài hơn độ dài khóa" hoặc "vượt quá phạm vi của khóa" nghĩa là gì
Độ dài bản mã RSA bằng số byte của khóa: khóa 2048 bit là 256 byte, viết dạng hex là 512 ký tự, không bao giờ dài hơn. Khi giải mã, bên cạnh tiêu đề ô khóa sẽ hiện "Bản mã N byte", hãy đối chiếu với số byte hiển thị cạnh ô đầu vào. Dài hơn khóa thường là do chọn sai định dạng đầu vào hoặc sao chép thừa nội dung; giá trị vượt quá phạm vi cho thấy bản mã này không được mã hóa bằng khóa công khai cùng cặp với khóa này, hãy đổi sang đúng khóa.
Mã hóa bằng khóa riêng, giải mã bằng khóa công khai có dùng để ký và xác minh chữ ký được không
Không dùng trực tiếp làm chữ ký được. Việc mã hóa bằng khóa riêng ở đây chỉ là áp dụng khóa riêng lên nội dung bạn nhập theo PKCS1Padding, không băm; còn chữ ký dạng SHA256withRSA thì băm dữ liệu trước, rồi đưa giá trị băm vào một cấu trúc cố định (DigestInfo). Vì vậy dùng khóa công khai ở đây giải một chữ ký chuẩn sẽ ra cấu trúc đó chứ không phải văn bản gốc. Muốn ký hoặc xác minh chữ ký, hãy dùng thư viện hoặc công cụ hỗ trợ các thuật toán như SHA256withRSA.
Lịch sử lưu những gì, có bị tải lên không
Chỉ lưu trong localStorage của trình duyệt trên thiết bị này và không bao giờ được tải lên; mã nguồn của trang không có yêu cầu mạng nào. Mỗi lần mã hóa hoặc giải mã thành công sẽ ghi một mục, giữ tối đa 20 mục, đầu vào hoặc kết quả vượt quá 20,000 ký tự thì không ghi. Mỗi mục có tham số, đầu vào và kết quả, cùng một dấu vân tay 8 ký tự tính từ khóa (8 ký tự hex đầu của SHA-256 của modulus, nằm sau dấu # trong mục, dùng để phân biệt có phải cùng một khóa hay không), không lưu bản thân khóa, nên sau khi bấm "Điền lại" bạn cần dán lại khóa. Bản rõ sau khi giải mã sẽ được lưu, dùng xong trên máy tính dùng chung hãy bấm "Xóa lịch sử".