История изменений
Исправление BruteForce, (текущая версия) :
Можно схему поподробнее описать?
- Генерим 3 случайных числа: ключ
K, начальный векторNи сольS. K 256bit, N 96bit, S 128bit. - Собираем
IDизKиS(HKDF на базе SHA-256). - Собираем строку дополнительной аутентификации
aad— это просто строка видаid=ID. - Если пользователь поставил пароль:
- Собираем ключ
Pkиз пароля иS(PBKDF2, SHA-256, 200000 итераций). Используется одна соль на всё. - Данные шифруются AES-GCM, ключ
Pk, вектор инициализацииNи подсовываетсяaad.
- К уже шифрованным данным (если был проль) или исходным (если пароль не стоял) дописывается двухбайтный тэг. Первый байт тэга значащий — означает, шифрованы ли данные паролем (
0x73) или нет (0x13). Второй байт — константа0x37. - Шифруем результат AES-GCM, тот же iv=
N, те жеaad. Это финальный шифротекстct. - Конкатенацией собирается строка байт blob=
N..S..ct. blobшлётся на сервер с указаниемID, сервер отдастblobименно по этомуIDи не имеет возможности подменить: клиент проверитIDсначала поNиKещё до выполнения расшифрования, а затем поaad.- Клиент остаётся с
K, на серверKне шлётся.Pkтоже, парольное вообще очищается. - Клиент формирует ссылку
origin/#ID/K. ЗдесьIDиKэто base64url-строки. - Когда получатель ссылки открывает её, то
- Браузер режет всё, что начинается с
#, это зовётсяlocation.hash. - С сервера загружается клиент (и это, я считаю, основная дырка. возвращаемся, можно сказать, к TLS-то дырявый; впрочем, никто не мешает держать клиент оффлайн; по-уму надо сделать отдальный клиент).
- Клиентсякий JS-код проверяет
location.hashи если он содержитIDиKстягивает с сервера данные. - Проверяет, дешифрует и, если надо, спрашивает пароль и дешифрует ещё.
Схема нуждается в аудите. Например, я не понимаю насколько небезопасно использовать в обоих случаях шифрования отдну и ту же соль и начальный вектор.
https://github.com/onetimesecret/onetimesecret/issues/281
Автор OTS не хочет поговорить публично(
Исходная версия BruteForce, :
Можно схему поподробнее описать?
- Генерим 3 случайных числа: ключ
K, начальный векторNи сольS. K 256bit, N 96bit, S 128bit. - Собираем
IDизKиS(HKDF на базе SHA-256). - Собираем строку дополнительной аутентификации
aad— это просто строка видаid=ID. - Если пользователь поставил пароль:
- Собираем ключ
Pkиз пароля иS(PBKDF2, SHA-256, 200000 итераций). Используется одна соль на всё. - Данные шифруются AES-GCM, ключ
Pk, вектор инициализацииNи подсовываетсяaad.
- К уже шифрованным данным (если был проль) или исходным (если пароль не стоял) дописывается двухбайтный тэг. Первый байт тэга значащий — означает, шифрованы ли данные паролем (
0x73) или нет (0x13). Второй байт — константа0x37. - Шифруем результат AES-GCM, тот же iv=
N, те жеaad. Это финальный шифротекстct. - Конкатенацией собирается строка байт blob=
N..S..ct. blobшлётся на сервер с указаниемID, сервер отдастblobименно по этомуIDи не имеет возможности подменить: клиент проверитIDсначала поNиKещё до выполнения расшифрования, а затем поaad.
Схема нуждается в аудите. Например, я не понимаю насколько небезопасно использовать в обоих случаях шифрования отдну и ту же соль и начальный вектор.
https://github.com/onetimesecret/onetimesecret/issues/281
Автор OTS не хочет поговорить публично(