BL2.ru

Разделение секрета по Шамиру онлайн (M из N)

Разделите секрет (пароль, мастер-фразу, приватный SSH-ключ целиком) на N долей. Любые M из них восстановят секрет, а M-1 долей не дают о нём никакой информации. Например, «2 из 3»: доли у трёх разных людей, и потеря одной не страшна.

🔒 Всё считается в вашем браузере (crypto.getRandomValues), секрет и доли никуда не отправляются.

Что такое схема Шамира

Схема разделения секрета Шамира (1979) делит секрет на N долей так, что любые M из них (порог) восстанавливают его, а любые M-1 не дают ни бита информации. Идея в том, что через M точек проходит ровно один многочлен степени M-1, а через M-1 точек - бесконечно много. Секрет это значение многочлена в нуле, доли это значения в точках 1..N. Остальные коэффициенты случайны, поэтому по M-1 долям любой секрет одинаково вероятен.

Зачем делить ключ

Классический сценарий - резервирование. Приватный ключ, мастер-пароль или фраза от кошелька не должны лежать в одном месте, но и потерять их нельзя. Делим «2 из 3» и раздаём доли разным людям или кладём в разные места (сейф, облако, дом родственника). Потеря одной доли не страшна, кража одной доли ничего не даёт. Для SSH-ключа вставьте его целиком, вместе со строками BEGIN и END, а ключ можно создать в генераторе SSH-ключей.

Чем отличается от разрезания ключа на куски

Если разрезать ключ на три части, каждая часть раскрывает треть секрета, а для восстановления нужны все три. Потерял один кусок - потерял ключ, а два куска сильно сужают перебор оставшейся части. В схеме Шамира одна доля (и любое число долей меньше порога) не раскрывает ничего, а порог гибкий: потеря N-M долей безопасна.

Как это устроено здесь

Секрет обрабатывается побайтово в поле GF(256) с полиномом AES 0x11b. Для каждого байта выбираются M-1 случайных коэффициентов (crypto.getRandomValues), доле с номером x достаётся значение многочлена в точке x. Восстановление - интерполяция Лагранжа в нуле. К секрету перед делением добавляются 4 байта контрольной суммы (начало SHA-256 секрета), они делятся вместе с ним. Поэтому одна доля не выдаёт хэш секрета, а при восстановлении ошибочный набор долей определяется: вместо мусора вы увидите сообщение.

Формат доли

bl2ss1-M-x-данные, где M - порог, x - номер доли (1..255), данные - значения доли для всех байт секрета и контрольной суммы в base64url. Пример: bl2ss1-2-1-Qm0x9kT2. Формат собственный, не совместим с ssss, Vault и другими программами.

Восстановление без сайта

Чтобы доли не зависели от этого сайта, ниже полный алгоритм восстановления. Декодируйте base64url в байты, возьмите M долей и вызовите функцию.

def mul(a, b):
    r = 0
    while b:
        if b & 1:
            r ^= a
        a <<= 1
        if a & 0x100:
            a ^= 0x11b
        b >>= 1
    return r

def inv(a):
    return next(x for x in range(1, 256) if mul(a, x) == 1)

def restore(points):  # points = [(x, y_bytes), ...], any M shares
    out = []
    for i in range(len(points[0][1])):
        s = 0
        for xi, yi in points:
            num = den = 1
            for xj, _ in points:
                if xj != xi:
                    num = mul(num, xj)
                    den = mul(den, xi ^ xj)
            s ^= mul(yi[i], mul(num, inv(den)))
        out.append(s)
    return bytes(out)  # the last 4 bytes are the checksum

Результат - секрет и 4 байта в конце. Проверьте, что они совпадают с первыми 4 байтами SHA-256 от секрета. Для надёжного пароля можно использовать генератор паролей.

Частые вопросы

Что даёт одна доля, если её украдут?
Ничего. Пока долей меньше порога M, любой секрет той же длины остаётся одинаково вероятным, это свойство самой схемы, а не вычислительная сложность. Перебор и будущие компьютеры тут не помогут.
Что будет, если вставить меньше долей, чем порог?
Математика выдала бы случайный мусор, поэтому в каждую долю записан порог, и инструмент сразу пишет, что долей мало. Если доли от разных секретов, не сойдётся контрольная сумма, и вы увидите ошибку, а не неверный результат.
Можно ли восстановить секрет другой программой, например ssss или Vault?
Нет. Формат bl2ss1 собственный, и доли читаются только этим инструментом. Зато в статье приведён короткий открытый алгоритм восстановления, так что секрет можно получить без сайта, на любом языке.
Какие M и N выбрать?
Для личного ключа обычно 2 из 3: потеря одной доли не страшна, а украсть нужно две. Для команды 3 из 5 или 4 из 7. Допустимы 2 ≤ M ≤ N ≤ 255. Чем выше порог, тем сложнее злоумышленнику и тем легче потерять доступ, если доли пропадут.
Не уходит ли мой секрет на сервер?
Нет. Секрет и доли обрабатываются только в вашем браузере, случайные числа берутся из crypto.getRandomValues. Но на общем компьютере закройте вкладку после работы и не оставляйте доли в буфере обмена.