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 розкриває закритий ключ (урок Sony ECDSA). Ця сторінка генерує випадковий k з crypto.getRandomValues, коли поле порожнє. Заповнюйте поле лише для відтворення відомого вектора для навчання чи тестування.
Ідентифікатор користувача(має збігатися з підписувачем)
Читати повідомлення як: Формат підпису:
r (hex)
s (hex)
✓ Підпис ДІЙСНИЙ
✗ Підпис НЕДІЙСНИЙ
Читати повідомлення як: Формат шифротексту: Вихід:
Фіксоване k (розширено):
Нагадування про гібридне шифрування: шифрування SM2 призначене для коротких таємниць (сесійних ключів, PIN-кодів), а не великих обсягів даних — кожне повідомлення платить 96 байтів накладних витрат C1+C3 і множення точки на еліптичній кривій. Зашифруйте випадковий ключ SM4/AES за SM2, потім дані симетричним шифром (сторінка SM4 / сторінка AES).
Читати шифротекст як: Порядок: Записувати відкритий текст як:
Перевірка з OpenSSL — шістнадцятковий 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) (замасковане повідомлення). Текст 2012 року GM/T 0003 з'єднував їх C1 ‖ C2 ‖ C3; стандарт 2016 року GB/T 32918.4 переставив на C1 ‖ C3 ‖ C2, і OpenSSL 1.1.1+ пішов за ним. Старі банківські й урядові системи досі говорять старим порядком — тому тут є обидва, плюс форма ASN.1 (SEQUENCE з INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2), яку видають деякі бібліотеки. Коли розшифрування не вдається з інструментом іншої сторони, перше, що варто перевірити, — порядок байтів.

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

Чи сумісний він з OpenSSL / GmSSL? Так. Шістнадцятковий вивід 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.