SM2/SM3/SM4 in Practice: Choosing, Integrating, and Debugging Chinese National Cryptography
National Crypto Is Not Optional — It Is Compliance
Developers working on government, banking, or state-owned-enterprise projects eventually hit the same sentence: "The system must support Chinese national cryptographic algorithms." This is not a preference — classified-protection 2.0 and the commercial cryptography evaluation write the SM family into acceptance criteria, and SHA-256 or RSA cannot substitute for SM3 or SM2 in those scopes. The most common first-contact mistake is forcing the international analogy: "SM3 is basically Chinese SHA-256, right?" Structurally true, but both endpoints must run the same algorithm family: a SHA-256 digest sent to an SM3-expecting peer fails verification forever, regardless of how "equivalent" the algorithms are on paper.
One sentence for selection:
| Need | Algorithm | International analogue |
|---|---|---|
| Symmetric encryption | SM4 | AES |
| Hash / digest | SM3 | SHA-256 |
| Signatures / asymmetric | SM2 | RSA / ECC |
Browser-local companions: SM4 encrypt/decrypt, SM3 hash, SM2 sign/encrypt — for minting test vectors and verifying intermediate results during integration, with nothing uploaded.
SM4: 90% of Integration Failures Die in One of Three Places
SM4 is a 128-bit block cipher, and "my ciphertext won't decrypt on their side" has a fixed debug order (by hit rate):
1. Key interpretation. SM4 keys are exactly 16 bytes. The classic mismatch: you use a UTF-8 string directly as the key ("1234567890abcdef" read as 16 characters) while the peer parses it as 32 hex chars decoded to 16 bytes — one string, two interpretations, guaranteed different ciphertexts. Pin down in writing: hex or raw utf8, and length counted in bytes, not characters.
2. Mode and IV. ECB takes no IV; CBC requires the same 16-byte IV on both ends. The typical symptom of mode misalignment: decryption succeeds without errors but the plaintext is garbage — with the first block readable and everything after wrong, the classic fingerprint of an IV offset. Real traffic should avoid ECB entirely (identical plaintext blocks produce identical ciphertext blocks, leaking structure); it belongs in connectivity tests only.
3. Output encoding. Hex or base64 for the ciphertext channel — all three parties (you, the peer, the spec) must fix the same convention. Listed last not because it is rare, but because once explicitly agreed it stops failing — the premise being that someone actually wrote it down.
A healthy debug habit: before touching code, both sides produce an expected ciphertext from a fixed plaintext and fixed key, and compare bytes. Finding the divergence point in a known-answer test is ten times faster than guessing against a black box.
SM3: Hash Mismatches Have Exactly One Cause
SM3 outputs a fixed 256 bits (64 hex characters). No key, no mode, no IV — so when two endpoints produce different digests, the cause is singular: the inputs differ. The usual suspects hiding in "identical-looking" inputs:
- Strings copied from documents carrying trailing newlines or spaces
- One side trimming, the other not
- JSON serialization differences (field order, whitespace) — digesting JSON requires an agreed canonical serialization
- Encoding drift: UTF-8 vs GBK producing completely different bytes for CJK input
The debug method: hex-dump both raw inputs and compare bytes, not eyeball-compare strings. A hash algorithm has no "compatibility problems" — it is deterministic, so identical inputs yield identical outputs. SM3 mismatch equals input mismatch, no third possibility.
SM2: Three Operations, Do Not Mix Them
SM2 is elliptic-curve; one integration usually involves three distinct operations:
- Encrypt/decrypt: public key encrypts, private key decrypts (for transporting sensitive data)
- Sign/verify: private key signs, public key verifies (proving "I sent this, unmodified")
- Key agreement: both parties derive a shared secret (connection setup; rarely exposed in tools)
The high-frequency trap: verification failures usually are not the signature algorithm's fault — they are the signed payload. The two ends disagree on what "the message" is: one signs the raw report, the other verifies against a newline-stripped version, or one with field-name prefixes added. Debug order: byte-compare the exact payload both ends believe they signed, then check that the key pair actually matches.
The key-management line deserves its own paragraph: test keys are free — the SM2 tool generates a pair locally and closes the loop (encrypt→decrypt, sign→verify) in seconds. Production private keys never enter any web page, script argument, or chat tool — production key custody belongs to key-management systems or hardware security modules, not to integration helpers.
SM2 Ciphertext Order: C1C3C2 vs C1C2C3
The second most common encrypt/decrypt failure is segment order. SM2 ciphertext is three concatenated pieces:
| Part | Meaning | Length (hex chars, uncompressed point) |
|---|---|---|
| C1 | Ephemeral curve point (x‖y; libraries often omit the 04 prefix) | 128 |
| C3 | Hash check value | 64 |
| C2 | Plaintext XOR stream | Variable with message length |
GB/T 32918.4-2016 recommends C1‖C3‖C2; many early SDKs and sample snippets still emit C1‖C2‖C3. When the orders disagree, decryption almost always fails — it looks like a wrong key, but the root cause is field packing. The on-site SM2 tool defaults to C1C3C2 and can switch to C1C2C3 so you have a known-good counterparty during integration.
Two more format noises worth writing into the interface contract:
- Public keys: uncompressed is
04+ 128 hex of coordinates (130 total); some peers hand you the bare 128 — prefix04. Compressed keys are02/03+ 64 hex of x. - Ciphertext prefix: some libraries wrap the whole ciphertext with an extra
04; if a peer blob starts with04and is oddly long, strip it before decrypt. This site's tool handles both common shapes automatically.
On the signature path, check separately: ASN.1 DER signatures versus raw r‖s (128 hex) are not interchangeable, and the SM3 userId used during hashing (often the default 1234567812345678) must match on both ends.
SM4 Encoding and IV: Treat Them as Contract
The "output encoding" row in the SM4 checklist deserves one more layer. This site's tool defaults to hex ciphertext and can switch to Base64 — same rule as AES interop: visually obvious, never guess. Under CBC the IV is 16 bytes (32 hex) and required; a missing or mismatched IV usually shows up as "decrypt succeeds but garbage plaintext, with the first block looking almost readable." Keys are likewise exactly 16 bytes: hex with a leading 0x or internal spaces should be normalized before the library sees them — otherwise you collide again with the "UTF-8 string of 16 characters used as the key" trap.
First integration run still wins: fixed plaintext + fixed key (+ fixed IV), both sides produce an expected ciphertext, align encoding and mode, then wire real business fields.
An Integration Self-Check Table
| Symptom | Check first |
|---|---|
| SM4 ciphertext rejected by peer | Key interpretation (hex/utf8) → mode and IV → output encoding (hex/Base64) |
| SM4 decrypts to garbage, first block fine | IV offset (classic CBC fingerprint) |
| SM4 CBC errors with "IV required" | Both ends passing a 16-byte IV |
| SM3 digests differ across ends | Invisible characters / trimming / encoding — inputs must differ |
| SM2 decrypt fails, key looks right | Ciphertext order C1C3C2 vs C1C2C3 → stray 04 prefix → public-key format |
| SM2 verification fails | Byte-compare signed payload → DER vs r‖s → userId → key-pair match |
| Nothing matches | Exchange a known-answer test vector first |
Coexistence with International Algorithms
Most systems in transition support both families: keep an algorithm switch in configuration (algorithm: SM4 | AES) and switch per integration channel as counterparties require. Tooling on both sides: alongside the SM family, the site carries AES encrypt/decrypt, RSA tools, and SHA-256 — running the same payload through both families and comparing is everyday practice during migration.
For the broader algorithm map and compliance framing, see the companion Chinese cryptography introduction; for GM/T vs GB/T vs ISO numbers, see the standard-number quick reference.
Triage notes
The three SM4 checkpoints are ordered by hit rate, and output encoding is deliberately last — 'not because it is rare, but because once it is agreed on it rarely goes wrong': the ordering follows error probability, not importance. The SM3 section compresses the verdict into one line, a mismatch means the inputs differ and there is no second possibility, because a hash is deterministic with no key or IV; the number-one repeat offender is invisible characters, so the method is a byte-by-byte hex-dump comparison, not 'the strings look the same'. SM2 verification failures likewise suspect the payload before the algorithm — the two ends disagreeing on what 'the signed content' is (line endings, field prefixes) is the high-frequency root cause.
Tools in this post are from ToolVault — developer tools run browser-local; keys and data never leave the device.
Related Tools
Related Articles
Post-Quantum Migration Self-Check: From Algorithm Inventory to Hybrid TLS — 12 Things to Do in 2026
A practical self-check framework for PQC migration: why three overlapping regulatory timelines make 2026 the starting line, how to build a cryptographic bill of materials (CBOM), ranking by HNDL exposure, enabling X25519+ML-KEM hybrid TLS, and what crypto-agility means in practice. With a 12-item checklist.
Passkeys, Explained: Why the Server Can No Longer Hold a Copy of Your Password
Passkeys (WebAuthn/FIDO2) deepened: registration vs assertion ceremonies, platform authenticators and roaming keys, synced passkeys, how they relate to passwords/TOTP/JWT, and why origin binding makes phishing resistance structural. Servers store public keys only; note that this site has no dedicated Passkey tool page.
ML-KEM, Explained: How Kyber Got Into Your TLS Handshake
An engineering tour of ML-KEM (FIPS 203, formerly Kyber): Kyber-to-standard naming, encapsulate/decapsulate and IND-CCA, the three parameter sizes, how X25519+ML-KEM feeds the TLS 1.3 HKDF schedule, the ClientHello-bloat middlebox trap, OpenSSL 3.5 / nginx enablement, and browser-side implementation boundaries.