SM2 шифрование / расшифровка / подпись

Полный набор инструментов открытого ключа SM2 на рекомендуемой кривой sm2p256v1 (GB/T 32918.5): создание пары ключей, подпись и проверка по схеме ZA на основе SM3 (GB/T 32918.2), а также шифрование и расшифровка в стандартном порядке C1C3C2, устаревшем порядке C1C2C3 или ASN.1 DER. Всё работает в браузере; ничего не загружается.
Закрытый ключ (hex, 64 цифры — обращайтесь как с паролем)
Открытый ключ (hex, 130 цифр с префиксом 04 или 128 цифр x||y)
Закрытый ключ используется для подписи и расшифровки, открытый — для проверки и шифрования. Ключи никогда не покидают эту страницу.
Идентификатор пользователя(«различающий идентификатор», подмешиваемый в ZA; по умолчанию — де-факто стандартный)
Читать сообщение как: Фиксированный k (продвинутое):
r (hex)
s (hex)
Подпись, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } — формат, который используют OpenSSL/GmSSL)
О поле фиксированного k: каждая настоящая подпись должна использовать новый непредсказуемый k — повторное использование или угадывание k раскрывает закрытый ключ (урок ECDSA у Sony). Эта страница генерирует случайный k через crypto.getRandomValues, когда поле пусто. Заполняйте поле, только чтобы воспроизвести известный вектор для обучения или тестов.
Идентификатор пользователя(должен совпадать с подписантом)
Читать сообщение как: Формат подписи:
r (hex)
s (hex)
✓ Подпись ДЕЙСТВИТЕЛЬНА
✗ Подпись НЕДЕЙСТВИТЕЛЬНА
Читать сообщение как: Формат шифртекста: Вывод:
Фиксированный k (продвинутое):
Напоминание о гибридном шифровании: шифрование SM2 предназначено для коротких секретов (сессионных ключей, PIN-кодов), а не для больших объёмов данных — каждое сообщение платит 96 байт накладных расходов C1+C3 и умножение точки на эллиптической кривой. Зашифруйте случайный ключ SM4/AES через SM2, затем данные симметричным шифром (страница SM4 / страница AES).
Читать шифртекст как: Порядок: Записать открытый текст как:
Перекрёстная проверка с OpenSSL — hex C1C3C2 этой страницы совпадает с openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem (OpenSSL 3.x с -pkeyopt ec_scheme:c1c3c2, по умолчанию), и инструментами GmSSL gmssl sm2randkey / sm2encrypt; подписи совпадают с openssl dgst -sm3 -sign с тем же идентификатором пользователя через -pkeyopt sm2_userid:1234567812345678. Ведущий байт 04 перед C1 (как выдают некоторые библиотеки) принимается при расшифровке.
Примечание о соответствии: SM2 — выбор алгоритма, продиктованный китайским соответствием коммерческой криптографии и совместимостью, со стойкостью, сравнимой с 256-битным ECC (NIST P-256). В промышленной эксплуатации сочетайте его с настоящей системой управления ключами или аппаратными ключами — страница в браузере — это калькулятор, а не хранилище.
Самопроверка
Повторяет вектора вывода ключа, подписи с фиксированным k и шифрования, полученные независимой эталонной реализацией на Python (и перекрёстно проверенные с gmssl), циклы DER-подписи и DER-шифртекста, циклы подписи и проверки, шифрования и расшифровки со случайным k, а также негативные пути (подделанный C3, обрезанный шифртекст, открытый ключ вне кривой, r = 0).
Что такое SM2?
Вкратце: SM2 — китайская национальная криптосистема с открытым ключом — схема эллиптической подписи и шифрования на фиксированной кривой sm2p256v1, опубликованная как GB/T 32918-2016 (ранее GM/T 0003-2012), играющая в китайском наборе «SM» ту же роль, что ECDSA/ECDH (P-256) в мире NIST.
ECC в одном абзаце (интуиция)

Вся криптография на эллиптических кривых держится на одном приёме: при базовой точке G на кривой над большим простым полем и кратной точке P = d·G вычислить d по P означает решить задачу дискретного логарифмирования на эллиптической кривой, для которой не известно быстрого алгоритма. Закрытый ключ d — просто 256-битное число; открытый ключ — точка d·G. SM2 — не новая арифметика кривых; это конкретный способ подписи (как ECDSA) и шифрования (как миниатюрный ECIES) на одной конкретной кривой с хешированием через SM3 вместо SHA.

sm2p256v1 против NIST P-256
Аспектsm2p256v1NIST P-256 (secp256r1)
Размер поля256-битное простое256-битное простое
Форма кривойy² = x³ + ax + by² = x³ − 3x + b (a = −3)
Уровень стойкости≈ 128 бит≈ 128 бит
ПодписьSM2 (GB/T 32918.2), на SM3, идентификатор пользователя связан с ZAECDSA с SHA-256
ШифрованиеSM2 (GB/T 32918.4), C1C3C2ECIES (ANSI X9.63, не стандартизирован NIST)
ХешSM3 (GB/T 32905)семейство SHA-2
Опубликованконструкция 2010, GM/T 0003-2012, GB/T 32918-2016; в ISO/IEC 14888-31999 (SEC 2 / NIST)
Поддержка TLSTLCP (GM/T 386) и наборы шифров TLS 1.3 по RFC 8998повсюду

Обе кривые дают одинаковую конкретную стойкость; ни у одной нет практической атаки. Выбор между ними определяется регуляторикой и совместимостью, а не стойкостью.

Идентификатор пользователя и ZA — что SM2 подписывает, а ECDSA не делает

Перед хешированием SM2 вплетает идентичность подписанта в дайджест: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA), где ENTLa — битовая длина ID, четыре средних поля закрепляют точную кривую, а последние два — открытый ключ подписанта. Сообщение хешируется как SM3(ZA ‖ M). Два следствия: подпись привязана к заявленной личности (это достоинство), а проверяющий должен знать идентификатор подписанта и использовать тот же (классическая ловушка совместимости). Почти вся экосистема остановилась на 16-значном значении по умолчанию 1234567812345678 — не из текста стандарта, а из примеров в приложении GM/T 0003; значение по умолчанию OpenSSL совпадает с ним, и с ним совпадает эта страница.

Форматы шифртекста: C1C3C2, C1C2C3 и DER

Шифртекст SM2 имеет три части: C1 = эфемерная точка kG (64 байта, x‖y), C3 = SM3(x2 ‖ M ‖ y2) (32 байта, целостность), C2 = M ⊕ KDF(x2 ‖ y2) (замаскированное сообщение). Текст GM/T 0003 2012 года конкатенировал их C1 ‖ C2 ‖ C3; стандарт GB/T 32918.4 2016 года переупорядочил в C1 ‖ C3 ‖ C2, и OpenSSL 1.1.1+ последовал ему. Старые банковские и государственные системы всё ещё говорят на старом порядке — поэтому на этой странице есть оба, плюс форма ASN.1 (SEQUENCE из INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2), которую выдают некоторые библиотеки. Когда расшифровка не удаётся с инструментом другой стороны, первое, что нужно проверить, — порядок байтов.

Распространённые ошибки
  • Повторное использование k или экономия на нём. Nonce k и при подписи, и при шифровании должен быть новым и непредсказуемым для каждой операции. Один повторённый k в двух подписях отдаёт закрытый ключ любому, кто видит обе. Эта страница берёт k из CSPRNG браузера; поля фиксированного k существуют только для воспроизведения известных векторов.
  • Несовпадающие идентификаторы пользователей. Подпишите со значением по умолчанию, а проверяйте с пользовательским (или наоборот) — и каждая верная подпись не пройдёт. Идентификатор входит в подписываемые данные.
  • Предположение о C1C3C2 повсюду. Системы эпохи GM/T 0003, некоторые смарт-карты и старые сборки GmSSL по умолчанию используют C1C2C3; некоторые инструменты также добавляют байт 04 некомпрессированной точки. Эта страница принимает всё это при расшифровке.
  • Шифрование больших объёмов данных SM2. Каждый шифртекст несёт 96 байт накладных расходов и стоит двух умножений точки. Используйте SM2 для ключа, SM4/AES для данных.
  • Восприятие открытого ключа с префиксом 04 как 65 сырых байт ключа. 04 — маркер кодирования: сам ключ — x ‖ y, 128 hex-цифр. Эта страница принимает оба написания.
Частые вопросы

Совместимо ли это с OpenSSL / GmSSL? Да. Hex-вывод C1C3C2 совпадает с openssl pkeyutl -sm2encrypt для того же открытого ключа, сообщения и k; подписи DER совпадают с выводом openssl dgst -sm3 -sign байт в байт (задайте идентификатор пользователя через -pkeyopt sm2_userid:...). Запуски со случайным k, разумеется, различаются — сравнивайте расшифровкой/проверкой, а не равенством.

Почему здесь нет обмена ключами SM2? GB/T 32918.3 определяет интерактивный аутентифицированный протокол обмена ключами; как однострочный калькулятор он не имеет смысла. Подпись и шифрование покрывают неинтерактивные сценарии.

Есть ли SM2 в WebCrypto? Нет — ни один браузер его не реализует (Chrome включает его только за нестандартными флагами, если вообще). Эта страница работает на реализации на JavaScript «с нуля», с приложенными к самопроверке выше собственными векторами приложения стандарта.

Можно ли использовать PEM-ключ из OpenSSL? Экспортируйте сырой hex: openssl ec -in key.pem -text печатает закрытый скаляр и открытую точку. Эта страница принимает только hex-ключи намеренно — механика PEM/SEC1 живёт на странице RSA, где ей место.

Тогда что такое SM9? Другое животное: криптография на основе идентичности, где любая строка (адрес электронной почты) и есть открытый ключ, а KGC выдаёт закрытые ключи. См. обзор SM9.