История изменений
Исправление 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 не хочет поговорить публично(