LINUX.ORG.RU

История изменений

Исправление BruteForce, (текущая версия) :

Можно схему поподробнее описать?

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

Схема нуждается в аудите. Например, я не понимаю насколько небезопасно использовать в обоих случаях шифрования отдну и ту же соль и начальный вектор.


https://github.com/onetimesecret/onetimesecret/issues/281

Автор OTS не хочет поговорить публично(

Исходная версия BruteForce, :

Можно схему поподробнее описать?

  1. Генерим 3 случайных числа: ключ K, начальный вектор N и соль S. K 256bit, N 96bit, S 128bit.
  2. Собираем ID из K и S (HKDF на базе SHA-256).
  3. Собираем строку дополнительной аутентификации aad — это просто строка вида id=ID.
  4. Если пользователь поставил пароль:
  • Собираем ключ Pk из пароля и S (PBKDF2, SHA-256, 200000 итераций). Используется одна соль на всё.
  • Данные шифруются AES-GCM, ключ Pk, вектор инициализации N и подсовывается aad.
  1. К уже шифрованным данным (если был проль) или исходным (если пароль не стоял) дописывается двухбайтный тэг. Первый байт тэга значащий — означает, шифрованы ли данные паролем (0x73) или нет (0x13). Второй байт — константа 0x37.
  2. Шифруем результат AES-GCM, тот же iv=N, те же aad. Это финальный шифротекст ct.
  3. Конкатенацией собирается строка байт blob=N..S..ct.
  4. blob шлётся на сервер с указанием ID, сервер отдаст blob именно по этому ID и не имеет возможности подменить: клиент проверит ID сначала по N и K ещё до выполнения расшифрования, а затем по aad.

Схема нуждается в аудите. Например, я не понимаю насколько небезопасно использовать в обоих случаях шифрования отдну и ту же соль и начальный вектор.


https://github.com/onetimesecret/onetimesecret/issues/281

Автор OTS не хочет поговорить публично(