Библиотека SJCL реализует механизм разделения секрета на основе схемы
Шамира (Shamir’s Secret Sharing), позволяя разложить один
криптографический ключ на несколько независимых фрагментов так, что
восстановление возможно только при наличии заданного минимального
количества частей.
Основная идея заключается в том, что секрет не хранится целиком ни в
одном месте. Вместо этого он представляется как точка многочлена высокой
степени, а каждая часть секрета — это значение этого многочлена в
определённой точке.
Математическая основа
разделения секрета
В основе схемы лежит полиномиальная интерполяция в конечном поле.
Секрет ( S ) кодируется как свободный член многочлена:
f(x) = S + a_1 x + a_2 x^2 + + a_{t-1} x^{t-1}
где:
- ( S ) — исходный секрет (ключ)
- ( t ) — порог восстановления (threshold)
- ( a_1, a_2, ) — случайные коэффициенты
Каждая доля (share) — это точка:
(x_i, f(x_i))
Для восстановления секрета требуется минимум ( t ) точек.
Архитектура sjcl.secret
В SJCL функциональность разделения секрета реализована через объект
sjcl.secret.
Он предоставляет два ключевых сценария:
- создание набора долей (shares)
- восстановление секрета из долей
Основной принцип:
- секрет → набор частей
- части → восстановление исходного секрета
Генерация частей секрета
Для разбиения ключа используется функция:
var shares = sjcl.secret.share(secret, numberOfShares, threshold);
Где:
secret — строка или бинарный ключ
numberOfShares — общее количество создаваемых
частей
threshold — минимальное количество частей для
восстановления
Пример:
var secret = "my-super-secret-key";
var shares = sjcl.secret.share(secret, 5, 3);
Результат:
- создаётся 5 независимых долей
- любые 3 из них достаточно для восстановления
- каждая доля выглядит как строка, содержащая закодированные
данные
Структура получаемых долей
Каждая доля содержит:
- идентификатор точки ( x )
- значение функции ( f(x) )
- служебные данные для восстановления
Пример формата:
1-abc123-def456-...
2-ghi789-jkl012-...
Важно понимать:
- каждая доля сама по себе не содержит информации о секрете
- одиночная доля математически бесполезна
Восстановление секрета
Для восстановления используется функция:
var secret = sjcl.secret.recover(sharesSubset);
Пример:
var recovered = sjcl.secret.recover([
shares[0],
shares[2],
shares[4]
]);
Условие:
- количество переданных долей должно быть ≥ threshold
- порядок долей не важен
Поведение при
недостаточном количестве частей
Если передано меньше порога:
sjcl.secret.recover([shares[0], shares[1]]);
результат:
- восстановление невозможно
- возвращается ошибка или некорректные данные (в зависимости от
реализации)
Это ключевая гарантия схемы Шамира: меньше порога →
информации о секрете не существует математически
Практическое применение
1. Разделение доступа к
приватному ключу
Типичный сценарий:
- 1 часть у сервера
- 1 часть у пользователя
- 1 часть у резервного хранилища
Без объединения всех частей ключ не восстанавливается.
2. Cold storage
криптовалютных ключей
- хранение seed-фразы в разделённом виде
- защита от компрометации одного устройства
3. Корпоративные системы
доступа
- разделение административного ключа между несколькими
участниками
- предотвращение одностороннего доступа
Безопасные параметры выбора
Ключевые параметры:
n — общее число долей
t — порог восстановления
Типичные конфигурации:
- (3,2) — минимальная защита
- (5,3) — баланс надёжности и удобства
- (10,5) — корпоративный уровень
Увеличение ( n ):
- повышает отказоустойчивость
Увеличение ( t ):
Криптографические свойства
Схема обеспечивает:
- информационную теоретическую стойкость
- отсутствие утечки при недостатке долей
- устойчивость к подделке без знания секрета
Если у злоумышленника есть ( t-1 ) долей:
- пространство возможных секретов остаётся полностью открытым
Ограничения реализации SJCL
Несмотря на математическую надёжность схемы:
- SJCL работает в JavaScript, что зависит от среды выполнения
- не защищает от компрометации памяти во время работы
- требует аккуратного обращения с хранением долей
Также:
- доли должны передаваться и храниться как чувствительные данные
- утечка threshold количества долей полностью раскрывает секрет
Сериализация и хранение
долей
Доли обычно сохраняются:
- в localStorage (не рекомендуется без шифрования)
- в файлах
- в QR-кодах
- на разных физических устройствах
Пример хранения:
localStorage.setItem("share1", shares[0]);
Практика:
- хранить каждую долю в отдельной среде
- избегать централизованного хранения
Восстановление на разных
устройствах
Типичный сценарий:
- пользователь вводит долю с устройства A
- добавляет долю с устройства B
- добавляет резервную долю с сервера
- система восстанавливает ключ
Комбинирование с шифрованием
Разделение секрета часто используется вместе с симметричным
шифрованием:
- ключ шифрования → делится через SJCL
- данные → шифруются AES внутри SJCL
Такой подход обеспечивает:
- защиту данных
- распределённое управление ключами
Ошибки при использовании
Частые проблемы:
- использование одинакового
threshold и n
без необходимости
- хранение всех долей на одном устройстве
- потеря одной доли при высоком пороге
- попытка восстановить секрет без проверки целостности
Модель угроз
Система защищает от:
- компрометации одного хранилища
- частичного доступа к данным
- утечки одиночных ключей
Но не защищает от:
- компрометации threshold количества узлов
- утечки во время восстановления
- XSS-атак в браузерной среде
Ключевая идея
использования sjcl.secret
Схема Shamir Secret Sharing в SJCL превращает единый уязвимый объект
(ключ) в распределённую систему, где безопасность определяется не
прочностью одного хранилища, а математической невозможностью
восстановления без достаточного числа независимых частей.