Мы разрабатываем одноранговое приложение с открытым исходным кодом, Мапео, предназначенный для пользователей с небольшим техническим опытом (без электронной почты или телефона) для сбора данных в офлайн-средах. Мы генерируем их идентификаторы на устройстве для каждого проекта в виде пары ключей с открытым и закрытым ключами, используя libsodium. crypto_sign_keypair
.
Для поддержки восстановления личности в случае потери устройства или переключения на новое устройство мы хотим использовать один главный ключ, который используется в качестве начального значения для всех остальных пар ключей. Пользователи запишут этот ключ и введут его вручную, чтобы восстановить свою личность (аналогично тому, как Биткойн использует списки слов BEP-39 для резервного копирования 256-битного ключа).
В идеале мы должны использовать 256-битное начальное число, которое поддерживается библиотекой libsodium. crypto_sign_seed_keypair
и обеспечивает много энтропии. Однако есть некоторые конструктивные ограничения:
- Списки слов BEP-39 являются хорошим решением для облегчения записи ключа, и может быть возможно записать 24 слова для 256-битного ключа, однако поддерживаются только 10 языков, и мы уже поддерживаем несколько языков, в которых нет слов. списки (например, тайский, кхмерский, вьетнамский).
- Большинство наших пользователей не имеют доступа к принтеру и используют мобильные устройства, поэтому им нелегко распечатать резервную копию ключа, например, в виде QR-кода.
- Лучшей кодировкой, которую мы придумали, является base-32, так как она позволяет избежать двусмысленных символов. Однако для 256-битного ключа с 32-битной CRC потребуется 57 символов в базе 32. В наших макетах дизайна это огромная случайная строка (даже отображаемая группами по 5 символов), и мы обеспокоены тем, что это приведет к ошибкам транскрипции.
- Поскольку многие пользователи используют нелатинские алфавиты, нам может потребоваться отобразить ключ в виде цифр (например,арабские цифры), так как они более понятны. Однако 256-битное число состоит из 77 цифр, которые трудно записать или ввести без ошибки.
Чтобы обойти эти ограничения, мой вопрос заключается в том, обеспечит ли 128-битный начальный/мастер-ключ достаточную энтропию для «достаточно хорошей» безопасности. Его легче записывать (30 символов с основанием 32 с CRC-16 или 44 цифры).
Я предлагаю получить 256-битное начальное число (для генерации пары ключей и получения подразделов) путем хеширования 128-битного начального числа с помощью Argon2 (см. libsodium pwhash).
Я понимаю, что это дает нам только 128-битную энтропию, но, поскольку она хэшируется до 256-битной с помощью Argon2, грубая сила будет дорогостоящей.
Я не эксперт по безопасности (возможно, вы уже поняли это!), но мой вопрос заключается в том, достаточно ли энтропии в этой идее 128-битного начального/мастер-ключа, чтобы сделать атаки грубой силы трудными/невозможными. Мы не ищем шифрование на уровне АНБ, но достаточное, чтобы решительный злоумышленник (возможно, спонсируемый государством) не смог провести брутфорс.
Это компромисс между удобством использования и безопасностью, мы хотим, чтобы приложение было достаточно простым для безопасного использования, а безопасность была достаточно хорошей, и я не уверен, где находится правильный баланс с точки зрения длины ключа / энтропии.