Думаете, реализация нонсов проста? Подумайте еще раз. Будь то создание ончейн-протоколов или оффчейн-инфраструктуры, правильная реализация нонсов является одной из самых сложных частей криптографической безопасности. Давайте разберемся, почему защита от повторного использования сложнее, чем кажется 👇
2/ Сначала давайте разберемся с цифровыми подписями. В криптографии с открытым ключом (например, BLS) у вас есть закрытый ключ, который подписывает сообщения, и открытый ключ, который их проверяет. В Ethereum: адрес = хэш открытого ключа сообщение = хэш транзакции подпись = 64 байта криптографического доказательства
3/ Вот в чем проблема: математика большинства криптопротоколов с открытым ключом не ограничивает, сколько раз подпись может быть проверена на одном и том же сообщении. Как только у вас есть действительная подпись, вы можете воспроизводить её бесконечно. Это открывает двери для атак повторного воспроизведения.
4/ Введите нонс: "число, используемое один раз", которое предотвращает атаки повторного воспроизведения. Когда потребитель получает сообщение с нонсом, он проверяет, использовался ли этот нонс ранее. Если да → отклонить. Транзакции Ethereum используют эту схему.
5/ Но реализация нонсов обманчиво сложна. Ключевые требования: - Нонсы НИКОГДА не должны быть повторно используемыми (на этой цепочке или других) - Должны предотвращать атаки повторного воспроизведения навсегда - Необходимы механизмы для управления ростом хранилища - Должны быть устойчивыми к атакам фронт-раннинга
6/ Наивное решение: хранить все нонсы в базе данных навсегда. Это имеет две основные проблемы: a) Неограниченный рост хранилища (особенно при спам-атаках) b) Уязвимость к атакам фронт-раннинга Проблема (a) легче решается, чем (b). Давайте сначала займемся хранилищем...
7/ Нонсы на основе временных меток решают проблему роста хранилища! Используйте временную метку + период истечения. Нонсы старше 5 минут удаляются из базы данных. Но что насчет одновременных сообщений с одной и той же учетной записи? Они делят одну временную метку. Решение: временная метка + random_bytes для гранулярной уникальности.
8/ Фронт-раннинг — это сложная часть. Злоумышленники могут перехватывать действительные подписи, выполнять фронт-раннинг, чтобы пометить нонсы как использованные, и тогда вызов законного пользователя будет отклонен. Это проблематично в ончейн-среде с пакетными операциями, если одна плохая подпись отклоняет всю партию. Для оффчейн: используйте шифрование TLS! Не позволяйте злоумышленникам видеть нонсы или подписи.
9/ Не забывайте о настойчивости! Если ваш кэш nonce хранится только в памяти, злоумышленники могут повторно использовать старые nonce после перезагрузки системы. Всегда сохраняйте состояние nonce в надежное хранилище и загружайте его при запуске. Кэши только в памяти = окно уязвимости для повторного использования.
10/ Уникальные нонсы для каждого потребителя! При трансляции нескольким пользователям каждый должен получить разное сообщение/подпись. В противном случае вы подвержены атакам «Человек посередине», когда один получатель пересылает сообщение, выдавая себя за оригинального отправителя.
11/ Инкрементные нонсы (как в Ethereum, нонс = предыдущий нонс + 1) имеют свое место, но будьте осторожны! Они создают огромные проблемы для оффчейн-инфраструктуры: сообщения в неправильном порядке, проблемы синхронизации и сложные сценарии восстановления. Используйте только если вы уверены, что сообщения будут (или должны) приходить в последовательности.
Резюме - Контрольный список реализации нонсов: ✅ Используйте нонсы для предотвращения атак повторного воспроизведения ✅ Сохраняйте состояние нонсов между перезагрузками ✅ Реализуйте механизмы истечения (метка времени + очистка) ✅ Делайте нонсы уникальными для каждого получателя ✅ Защищайтесь от фронт-раннинга с помощью зашифрованных каналов ✅ Избегайте инкрементальных нонсов, если порядок не гарантирован Безопасность заключается в деталях! 🛡️
1,37K