跪拜 Guibai
← Back to the summary

China's SM2 and SM3: The Two Locks Every Gateway Request Must Pass

Two Locks in One Request: Understanding China's SM2 and SM3 with Diagrams

When integrating with government, financial, or enterprise open platforms, many developers first encounter "national cryptographic algorithms" (national commercial cryptography standards).

Interface documentation often opens with a requirement like: "To guarantee transmission security, all gateway requests use SM2 encryption and SM3 signing."

Yet during joint debugging, the most frequent console errors are these frustrating failures:

The root cause is often that many people treat "signing" and "encryption" as the same thing, leading to conceptual confusion, reversed call order, and using the wrong keys.

In fact, a single request contains two fundamentally different operations:

This article will step by step break down how these two locks work, how they cooperate, and practical troubleshooting tips, so you can understand SM2 and SM3 at once.


1. Mental Model: Sending an Important Package

To fully grasp their division of labor, imagine an API request from the frontend to the gateway as sending a package containing an important contract:

┌─────────────────────────────────────────────────────────────────┐
│ 📄 Business Body (e.g., ID card, phone number, bank card)       │
└────────────────────────────────┬────────────────────────────────┘
                                 │
                                 ▼
┌─────────────────────────────────────────────────────────────────┐
│ 🔒 First Lock: SM2 = "Put into a password safe" (anti-eavesdropping, only needed on specific sensitive interfaces) │
│ • Use the platform's [public key] to lock plaintext into the safe, turning it into a garbled ciphertext │
│ • Even if a hacker captures the package, without the [private key] they cannot open or understand it │
└────────────────────────────────┬────────────────────────────────┘
                                 │
                                 ▼
┌─────────────────────────────────────────────────────────────────┐
│ 🏷️ Second Lock: SM3 = "Attach an anti-tamper seal" (anti-tampering, required for all gateway requests) │
│ • Arrange the package label (including app ID, timestamp, safe ciphertext) │
│ • Use SM3 to compute a unique 64-character tamper-proof fingerprint (sign) and attach it on the package seal │
│ • Even if someone silently changes one punctuation mark, the gateway recomputes the fingerprint and it won't match, so the request is rejected │
└─────────────────────────────────────────────────────────────────┘

Compare the key dimensions of the two locks:

Dimension SM3 Signing (tamper-proof seal) SM2 Encryption (password safe)
International counterpart SHA-256, MD5 (hash/digest) RSA, ECC (asymmetric public/private key encryption)
Can it reverse the plaintext? Absolutely not (one-way fingerprint, irreversible) Yes (public key encryption → private key decryption)
Core defense goal Anti-tampering: ensure data is not subtly altered during transmission Anti-eavesdropping: protect sensitive personal privacy and business data
Required per request? Always (anything going through the gateway must include it) On demand (only sensitive interfaces or when background has encryption enabled)
Key configuration needed? No key (pure mathematical hash, public algorithm) Must have key pair (public key encrypts, private key decrypts)

After understanding this high-level mental model, we dig deeper into the technical details of both locks.


2. Deep Dive into the First Lock: SM3 "Tamper-Proof Seal"

2.1 What is SM3?

SM3 is a cryptographic hash algorithm published by the State Cryptography Administration of China (commercial cryptography GM/T 0004). Its role is equivalent to SHA-256 in the international cryptographic system.

SM3 has three core properties:

  1. One-way irreversible: You can easily compress a long text of millions of characters via SM3 into a 64-character hex string, but no one in the world can recover the original from that 64-character string.
  2. Fixed output length: Whether the input is empty "", a few words, or a multi-gigabyte file, SM3 always outputs a fixed 256 bits (i.e., 32 bytes, or 64 hex characters).
  3. Highly sensitive avalanche effect: If the plaintext changes by just 1 bit (for example, a comma becomes a period), the resulting 64-character hash changes drastically and unpredictably.

2.2 How the Gateway Verifies Signatures with SM3

In an open platform, the client and gateway agree on a standard verification flow:

sequenceDiagram
    autonumber
    participant Client as Client (frontend/App)
    participant Hacker as Man-in-the-middle (capture/proxy)
    participant Gateway as Business Gateway (Gateway)

    Note over Client: 1. Extract request fields, sort by ASCII ascending<br/>2. Concatenate as key1=val1&key2=val2...<br/>3. Compute SM3: sign = sm3Hex(concatenated string)
    Client->>Hacker: Send POST request (all params + sign)
    Note over Hacker: Assume hacker tampers with a parameter:<br/>e.g., amount=100 becomes amount=99999
    Hacker->>Gateway: Forward tampered request
    Note over Gateway: 4. Gateway sorts and concatenates received fields by same rules<br/>5. Gateway recomputes an SM3 hash
    alt Gateway recomputed SM3 === client's sign
        Gateway-->>Client: ✅ Verification passed, continue business
    else mismatch
        Gateway-->>Client: ❌ Block request! Error: signature verification failed
    end

Because of the avalanche effect, if a hacker alters even a single parameter value during transmission, the fingerprint the gateway recomputes with SM3 will inevitably differ from the sign sent by the client, exposing the tampering immediately.

2.3 Three High-Frequency Pitfalls in SM3 Signing

When writing signature code, these details can cause gateways to report "verification failed" if overlooked:

  1. Dictionary-order sorting (ascending ASCII) : Parameter names involved in signing must be sorted by ASCII dictionary order. For example, app_id comes before biz_content, and biz_content comes before charset.
  2. Null-value filtering rules: In most gateway specifications, parameters with values of null, undefined, or empty string "" do not participate in signature concatenation. If the client includes version=&... while the gateway excludes version when computing, the concatenated strings differ and verification fails.
  3. Don't blindly put passthrough fields and headers into the signed string: Many interfaces include HTTP headers (like Authorization, certify_token) or external passthrough fields (like header={"userid":"..."}). Unless the interface docs explicitly say so, these transport-layer fields usually do not belong to the signature set; adding them is overreach.

3. Deep Dive into the Second Lock: SM2 "Password Safe"

3.1 What is SM2?

SM2 is an asymmetric cryptography algorithm based on elliptic curve cryptography (ECC) (commercial cryptography GM/T 0003), on the international stage it is mainly the counterpart of RSA.

Compared to traditional RSA-2048, SM2 (256-bit elliptic curve) offers equivalent or even higher security strength, but shorter keys, faster computation, and smaller ciphertext over the network.

The core of asymmetric encryption is a key pair:

3.2 Question: Why Does the Frontend Configuration Include Both Public and Private Keys?

Junior developers are often puzzled by a "security common sense": "Shouldn't the private key never be exposed to the frontend/client? Why does the gateway integration doc ask the frontend to configure both keys?"

This is because in many lightweight government and enterprise gateway scenarios, bidirectional encrypted communication is implemented:

Untitled diagram-2026-10-28-062840.png

The two key pairs each serve their own purpose, ensuring two-way anti-eavesdropping on the entire transmission loop.

3.3 Why Do Most SM2 Ciphertexts Start with 04?

If you look closely at SM2-encrypted hex strings, you'll notice almost all start with 04:

04c852914e34a6bc8910... (followed by a long hex string)

This is no coincidence; it is the standard indicator of uncompressed elliptic curve point format in cryptographic specifications:

Practical pitfalls:

3.4 Mode Pitfall: C1C3C2 or C1C2C3?

SM2 ciphertext consists of three parts:

Historically there are two arrangement modes:

  1. Old national standard: C1C2C3
  2. New national standard and mainstream spec: C1C3C2

Most mainstream government and financial gateways now uniformly use C1C3C2 (e.g., in sm-crypto, set cipherMode to 1). If the gateway uses C1C3C2 but your client is configured for C1C2C3, even with perfectly paired keys, decryption will fail!


4. The Final Combination: The Dressing Order of the Two Locks

When a request requires both SM2 encryption and SM3 signing, there is only one order, and it cannot be reversed!

Iron rule: lock the safe first, then attach the seal!

sequenceDiagram
    autonumber
    participant App as Business Code
    participant GatewaySDK as Request Wrapper Layer
    participant Network as Gateway (gateway.do)

    App->>GatewaySDK: Pass plaintext business object { "phone": "138..." }
    Note over GatewaySDK: Step 1: SM2 encryption<br/>Turn plaintext into ciphertext: "04a1b2..."
    Note over GatewaySDK: Step 2: Dictionary-order concatenation<br/>Put ciphertext into biz_content!<br/>app_id=...&biz_content=04a1b2...&timestamp=...
    Note over GatewaySDK: Step 3: Compute SM3 seal<br/>sign = sm3Hex(string to be signed)
    GatewaySDK->>Network: Send POST request (contains ciphertext biz_content and sign)
    Note over Network: Step 4: Gateway first verifies signature (SM3)<br/>Recompute hash from ciphertext, compare sign<br/>(only after verification passes does it start SM2 private key decryption)

Why the Reverse Order Is Doomed to Fail?

Suppose you make the logical error: compute the signature on plaintext first, then encrypt the body.

  1. When the client computes the signature, it uses the plaintext string biz_content={"phone":"138..."};
  2. After signing, you encrypt biz_content into 04a1b2...;
  3. The gateway receives the request, sees only the ciphertext 04a1b2..., and recomputes SM3 on the ciphertext;
  4. Result: the hash from the ciphertext can never equal the signature computed on the plaintext, so the gateway rejects it in the first step of verification as "illegal tampering" and never reaches decryption!

5. Joint Debugging Quick Reference Checklist

Next time you hit an error, run through this checklist item by item:

🛠️ When you encounter "Signature verification failed (SM3)"

🔓 When you encounter "Decryption failure (SM2)"


6. Summary

Understanding the essence of SM2 and SM3 is just this diagram and a sixteen-character phrase:

                  ┌──────────────────────┐
                  │      Business Request │
                  └──────────┬───────────┘
                             │
            【First Lock】     ▼
         SM2 Encryption (reversible)   [ 04... ciphertext safe ]  ---> solves "others cannot understand"
                             │
            【Second Lock】    ▼
         SM3 Signature (irreversible) [ 64-character tamper-proof seal sign ] ---> solves "others cannot alter"

Sixteen-character phrase for debugging: Public key locks the safe, ciphertext gets the seal; encrypt first, sign second; decrypt on return with private key.

Once you separate the roles and get the order right, connecting to a national-cryptography gateway is no mystery.