SM2 암호화 / 복호화 / 서명

권장 곡선 sm2p256v1(GB/T 32918.5) 위의 완전한 SM2 공개 키 도구 상자: 키 쌍 생성, SM3 기반 ZA 방식(GB/T 32918.2)으로 서명과 검증, 표준 C1C3C2 순서, 레거시 C1C2C3 순서 또는 ASN.1 DER로 암호화와 복호화. 모든 처리는 브라우저에서 이루어지며 아무것도 업로드되지 않습니다.
개인 키 (hex, 64자리 — 비밀번호처럼 취급)
공개 키 (hex, 04 접두 포함 130자리 또는 x||y 128자리)
개인 키는 서명과 복호화에 쓰이고, 공개 키는 서명 검증과 암호화에 쓰입니다. 키는 절대 이 페이지를 떠나지 않습니다.
사용자 ID(ZA에 섞이는 "사용자 식별자"; 기본값은 사실상의 표준입니다)
메시지 읽기: 고정 k (고급):
r (hex)
s (hex)
서명, ASN.1 DER (SEQUENCE { r INTEGER, s INTEGER } — OpenSSL/GmSSL이 쓰는 형식)
고정 k 상자에 대하여: 실제 서명은 매번 새롭고 예측 불가능한 k를 써야 합니다 — k를 재사용하거나 추측하게 되면 개인 키가 샙니다(소니 ECDSA의 교훈). 이 페이지는 상자가 비어 있으면 crypto.getRandomValues로 무작위 k를 만듭니다. 상자를 채우는 것은 교육이나 테스트를 위해 알려진 벡터를 재현할 때뿐입니다.
사용자 ID(서명자의 것과 같아야 합니다)
메시지 읽기: 서명 형식:
r (hex)
s (hex)
✓ 서명이 유효합니다
✗ 서명이 무효입니다
메시지 읽기: 암호문 형식: 출력:
고정 k (고급):
하이브리드 암호화 알림: SM2 암호화는 짧은 비밀(세션 키, PIN)용이지 대량 데이터용이 아닙니다 — 메시지마다 96바이트의 C1+C3 오버헤드와 타원곡선 점 곱셈이 붙습니다. 무작위 SM4/AES 키를 SM2로 암호화한 뒤 데이터는 대칭 암호로 처리하세요(SM4 페이지 / AES 페이지).
암호문 읽기: 순서: 평문 쓰기:
OpenSSL 교차 검증 — 이 페이지의 C1C3C2 hex는 openssl pkeyutl -sm2encrypt -pubin -inkey pub.pem(OpenSSL 3.x, -pkeyopt ec_scheme:c1c3c2 기본값)과 GmSSL의 gmssl sm2randkey / sm2encrypt 도구와 일치하며, 서명은 같은 사용자 ID로 -pkeyopt sm2_userid:1234567812345678를 쓴 openssl dgst -sm3 -sign과 일치합니다. 복호화 시 C1 앞의 04 바이트(여러 라이브러리가 만듦)도 받아들입니다.
준수 참고: SM2는 중국 상용암호 준수와 상호운용이 이끄는 알고리즘 선택이며 보안은 256비트 ECC(NIST P-256)와 대등합니다. 프로덕션에서는 진짜 키 관리 시스템이나 하드웨어 키와 짝지으세요 — 브라우저 페이지는 계산기이지 금고가 아닙니다.
자체 테스트
독립적인 Python 참조 구현이 만들어낸 키 유도, 고정 k 서명, 암호화 벡터를 재생하고(gmssl과 교차 확인), DER 서명과 DER 암호문 왕복, 무작위 k의 서명/검증 및 암복호화 왕복, 그리고 역방향 경로(C3 변조, 암호문 절단, 곡선 위에 없는 공개 키, r = 0)까지 확인합니다.
SM2란?
한 문장 요약: SM2는 중국 국가 표준 공개 키 암호 시스템입니다 — 고정 곡선 sm2p256v1 위의 타원곡선 서명 및 암호화 방식으로 GB/T 32918-2016(이전 GM/T 0003-2012)으로 공표되었으며, NIST 세계에서 ECDSA/ECDH(P-256)가 맡은 역할을 중국 "SM" 제품군에서 맡습니다.
ECC 한 문단 요약 (직관)

모든 타원곡선 암호는 하나의 트릭에 기댑니다. 큰 소수체 위 곡선의 기저점 G와 배수 P = d·G가 주어졌을 때 P에서 d를 계산하는 것은 타원곡선 이산대수 문제를 푸는 것이며 빠른 알고리즘이 알려지지 않았습니다. 개인 키 d는 그냥 256비트 숫자이고 공개 키는 점 d·G입니다. SM2는 새로운 곡선 연산이 아닙니다 — 하나의 특정 곡선에서 서명은 (ECDSA처럼) 암호화는 (축소판 ECIES처럼) 하는 특정한 방식이며, SHA 대신 SM3로 해시합니다.

sm2p256v1 vs 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 기반, 사용자 ID가 ZA에 묶임SHA-256을 쓴 ECDSA
암호화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 11999년 (SEC 2 / NIST)
TLS 지원TLCP (GM/T 386)와 TLS 1.3 RFC 8998 스위트어디서나

두 곡선 모두 같은 구체적 보안을 제공하며 어느 쪽에도 실용적 공격이 없습니다. 둘 사이의 선택은 규제와 상호운용의 문제이지 강도가 아닙니다.

사용자 ID와 ZA — SM2가 서명하고 ECDSA가 하지 않는 것

해시 전에 SM2는 서명자의 신원을 다이제스트에 접습니다: ZA = SM3(ENTL ‖ ID ‖ a ‖ b ‖ xG ‖ yG ‖ xA ‖ yA). ENTLa는 ID의 비트 길이, 가운데 네 필드는 정확한 곡선을 고정하고 마지막 둘은 서명자의 공개 키입니다. 메시지는 SM3(ZA ‖ M)로 해시됩니다. 두 가지 결과: 서명이 주장된 신원에 묶입니다(기능), 검증자에게 서명자의 ID를 알려주고 같은 것을 써야 합니다(고전적 상호운용 함정). 생태계 대부분은 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 형식(INTEGER x1, INTEGER y1, OCTET STRING C3, OCTET STRING C2의 SEQUENCE)까지 받습니다. 상대방 도구와 복호화가 실패하면 바이트 순서가 가장 먼저 확인할 것입니다.

흔한 실수
  • k 재사용 또는 소홀. 서명과 암호화 양쪽의 논스 k는 작업마다 새롭고 예측 불가능해야 합니다. 서명 두 개에서 k가 한 번 반복되는 순간 둘을 보는 누구에게 개인 키를 넘깁니다. 이 페이지는 브라우저 CSPRNG에서 k를 뽑으며, 고정 k 상자는 알려진 벡터 재현용일 뿐입니다.
  • 사용자 ID 불일치. 기본 ID로 서명하고 다른 ID로 검증하면(혹은 반대로) 모든 유효한 서명이 실패합니다. ID는 서명된 데이터의 일부입니다.
  • 어디서나 C1C3C2라고 가정. GM/T 0003 시대 시스템, 일부 스마트카드, 오래된 GmSSL 빌드는 C1C2C3이 기본이며, 몇몇 도구는 비압축 점 04 바이트를 앞에 붙입니다. 이 페이지는 복호화에서 이 모두를 받아들입니다.
  • SM2로 대량 데이터 암호화. 각 암호문에 96바이트 오버헤드가 붙고 점 곱셈 두 번이 듭니다. 키에는 SM2, 데이터에는 SM4/AES를 쓰세요.
  • 04 접두 공개 키를 65바이트 날 키로 취급. 04는 인코딩 표지입니다. 키 자체는 x ‖ y의 128 hex 자리입니다. 이 페이지는 두 표기 모두 받습니다.
FAQ

OpenSSL / GmSSL과 호환되나? 네. C1C3C2 hex 출력은 같은 공개 키, 메시지, k에 대해 openssl pkeyutl -sm2encrypt와 일치하고 DER 서명은 openssl dgst -sm3 -sign 출력과 바이트 단위로 일치합니다(사용자 ID는 -pkeyopt sm2_userid:...로 설정). 무작위 k 실행은 물론 달라집니다 — 동등성이 아니라 복호화/검증으로 비교하세요.

여기 SM2 키 교환이 없는 이유는? GB/T 32918.3은 상호 인증 키 교환 프로토콜을 정의하며 한 페이지 계산기로는 의미가 없습니다. 서명과 암호화가 비대화형 용도를 덮습니다.

SM2가 WebCrypto에 있나? 아니요 — 어떤 브라우저도 구현하지 않습니다(Chrome은 기껏해야 비표준 플래그 뒤에). 이 페이지는 처음부터 쓴 JavaScript 구현을 돌리며 표준 자체의 부록 벡터를 위 자체 테스트에 연결했습니다.

OpenSSL의 PEM 키를 쓸 수 있나? 대신 날 hex를 내보내세요: openssl ec -in key.pem -text가 개인 스칼라와 공개 점을 인쇄합니다. 이 페이지는 의도적으로 hex 키만 받습니다 — PEM/SEC1 장비는 그것이 속한 RSA 페이지에 있습니다.

그럼 SM9는 무엇인가요? 전혀 다른 것입니다: ID 기반 암호로, 어떤 문자열(이메일 주소)이든 곧 공개 키이고 KGC가 개인 키를 발급합니다. SM9 개요 페이지를 참고하세요.