Chúng tôi đang phát triển một ứng dụng ngang hàng mã nguồn mở, Mapeo, được thiết kế cho người dùng có kinh nghiệm kỹ thuật thấp (và không có email hoặc điện thoại) để thu thập dữ liệu trong môi trường ngoại tuyến. Chúng tôi đang tạo danh tính của họ trên thiết bị cho từng dự án dưới dạng cặp khóa công khai-riêng tư bằng cách sử dụng libsodium crypto_sign_keypair
.
Để hỗ trợ khôi phục danh tính trong trường hợp mất thiết bị hoặc chuyển sang thiết bị mới, chúng tôi muốn sử dụng một khóa chính duy nhất được dùng làm khóa gốc cho tất cả các cặp khóa khác. Người dùng sẽ ghi lại khóa này và nhập thủ công để khôi phục danh tính của họ (tương tự như cách Bitcoin sử dụng danh sách từ BEP-39 để sao lưu khóa 256 bit).
Lý tưởng nhất là chúng tôi sẽ sử dụng hạt giống 256 bit, đây là thứ được hỗ trợ bởi libsodium's crypto_sign_seed_keypair
và cung cấp nhiều entropy. Tuy nhiên, có một số hạn chế về thiết kế:
- Danh sách từ BEP-39 là một giải pháp tốt để tạo điều kiện viết ra một khóa và có thể quản lý để viết ra 24 từ cho một khóa 256 bit, tuy nhiên, chỉ có 10 ngôn ngữ được hỗ trợ và chúng tôi đã hỗ trợ nhiều ngôn ngữ không có từ danh sách (ví dụ: tiếng Thái, tiếng Khmer, tiếng Việt).
- Hầu hết người dùng của chúng tôi không có quyền truy cập vào máy in và đang sử dụng thiết bị di động, vì vậy, không có cách nào dễ dàng để họ in bản sao lưu khóa của họ dưới dạng mã QR chẳng hạn.
- Mã hóa tốt nhất mà chúng tôi nghĩ ra là cơ số 32, vì mã này tránh các ký tự không rõ ràng. Tuy nhiên, khóa 256 bit có CRC 32 bit sẽ cần 57 ký tự trong cơ số 32. Trong các mô hình thiết kế của chúng tôi, đây là một chuỗi ngẫu nhiên áp đảo (thậm chí được hiển thị theo nhóm 5 ký tự) và chúng tôi lo ngại rằng nó sẽ dẫn đến lỗi sao chép.
- Vì nhiều người dùng sử dụng bảng chữ cái không phải chữ cái Latinh, nên chúng tôi có thể cần hiển thị khóa dưới dạng số (ví dụ:chữ số Ả Rập) vì chúng được hiểu rộng rãi hơn. Tuy nhiên, một số 256 bit có 77 chữ số, rất khó để ghi hoặc nhập mà không gặp lỗi.
Để khắc phục những hạn chế này, câu hỏi của tôi là liệu khóa gốc/khóa chính 128 bit có cung cấp đủ entropy để bảo mật "đủ tốt" hay không. Viết ra dễ quản lý hơn (30 ký tự cơ số 32 với CRC-16 hoặc 44 chữ số).
Tôi đề xuất lấy một hạt giống 256 bit (để tạo cặp khóa giống và lấy các khóa con) bằng cách băm hạt giống 128 bit bằng Argon2 (xem pwhash libsodium).
Tôi nhận ra rằng điều này chỉ mang lại cho chúng tôi 128-bit entropy, nhưng vì nó được băm thành 256-bit bằng Argon2 nên sẽ rất tốn kém cho lực lượng vũ phu.
Tôi không phải là chuyên gia bảo mật (bây giờ bạn có thể đã thu thập được điều đó!) nhưng câu hỏi của tôi là liệu ý tưởng về khóa gốc/khóa chính 128 bit này có đủ entropy để khiến các cuộc tấn công vũ phu trở nên khó khăn/không thể thực hiện được hay không. Chúng tôi không tìm kiếm mã hóa cấp NSA, nhưng đủ để ngăn kẻ tấn công quyết tâm (có thể được nhà nước bảo trợ) không thể thực hiện vũ phu.
Đó là sự thỏa hiệp giữa khả năng sử dụng và bảo mật, chúng tôi muốn giữ cho ứng dụng đủ dễ sử dụng một cách an toàn và giữ bảo mật đủ tốt và tôi không chắc đâu là sự cân bằng phù hợp về độ dài khóa/entropy.