Guia Completo de Criptografia SM2: Geração de Chaves, Criptografia, Descriptografia e Assinatura Digital na Prática

Codificação

O que é SM2?

SM2 é um algoritmo de criptografia assimétrica publicado pela Administração Nacional de Criptografia da China, baseado em criptografia de curva elíptica (ECC), substituindo RSA como padrão nacional.

Comparação SM2 RSA 2048
Comprimento da chave 256 bit 2048 bit
Intensidade de segurança 128 bit 112 bit
Velocidade de assinatura ~0.5ms ~3ms
Velocidade de verificação ~1ms ~0.1ms
Razão do comprimento da chave 1 8
Padrão nacional GM/T 0003 PKCS#1

SM2 atinge a intensidade de segurança do RSA 2048 bit com uma chave de 256 bit, chave mais curta, velocidade mais rápida.


Três Usos do SM2

Uso Descrição Ferramenta Correspondente
Criptografia/Descriptografia Criptografar com chave pública, descriptografar com chave privada Criptografia SM2
Assinatura Digital Assinar com chave privada, verificar com chave pública Assinatura SM2
Acordo de Chaves Ambas as partes negociam uma chave compartilhada Protocolo ECDH

Passo 1: Gerar Par de Chaves SM2

Usar a ferramenta do ToolsKu

  1. Abrir Ferramenta de Criptografia SM2
  2. Clicar em "Gerar par de chaves"
  3. Obter a chave pública e a chave privada

Usar a linha de comando

# Instalar gmssl
brew install gmssl  # macOS
# Ou baixar de https://github.com/guanzhi/GmSSL/releases

# Gerar par de chaves SM2
gmssl sm2 -genkey -out sm2.key

# Ver as chaves
gmssl sm2 -in sm2.key -text

Usar JavaScript

import { sm2 } from 'sm-crypto';

// Gerar par de chaves
const keyPair = sm2.generateKeyPairHex();
// keyPair.privateKey → chave privada (64 hexadecimais)
// keyPair.publicKey  → chave pública (128 hexadecimais, 04 + X + Y)

console.log('Chave privada:', keyPair.privateKey);
console.log('Chave pública:', keyPair.publicKey);

Formato da chave

Formato da chave pública SM2:
04 || X (32 bytes) || Y (32 bytes)
↓
04 + 64 hexadecimais X + 64 hexadecimais Y
Comprimento total: 130 caracteres hexadecimais (65 bytes)

Formato da chave privada SM2:
Número aleatório de 32 bytes
Comprimento total: 64 caracteres hexadecimais (32 bytes)

Passo 2: Criptografia e Descriptografia SM2

Fluxo de Criptografia

Texto simples → Criptografia SM2 (chave pública) → Texto cifrado (C1 || C3 || C2)
  • C1: Ponto da curva elíptica (65 bytes)
  • C3: Hash SM3 (32 bytes)
  • C2: Dados cifrados

Usar a ferramenta do ToolsKu

  1. Abrir Ferramenta de Criptografia SM2
  2. Colar a chave pública
  3. Inserir o texto simples a ser criptografado
  4. Selecionar o formato do texto cifrado (C1C3C2 ou C1C2C3)
  5. Clicar em "Criptografar" para obter o texto cifrado

Usar JavaScript

import { sm2 } from 'sm-crypto';

const publicKey = '04...'; // 128 hexadecimais
const privateKey = '...';  // 64 hexadecimais

// Criptografar (formato C1C3C2 por padrão)
const cipherText = sm2.doEncrypt('Olá SM2', publicKey, 1);
// Parâmetro 1 = formato C1C3C2 (recomendado pelo padrão nacional)
// Parâmetro 0 = formato C1C2C3 (compatibilidade com versão antiga)

console.log('Texto cifrado:', cipherText);

// Descriptografar
const plainText = sm2.doDecrypt(cipherText, privateKey, 1);
console.log('Texto simples:', plainText); // "Olá SM2"

Formatos de codificação do texto cifrado

Formato Descrição Cenário de uso
C1C3C2 Formato recomendado pelo padrão nacional Projetos novos (padrão)
C1C2C3 Formato de versão antiga Compatibilidade com sistemas antigos
ASN.1 Codificação DER Interoperabilidade Java/C#

Passo 3: Assinatura Digital SM2

Fluxo de Assinatura

Mensagem → Hash SM3 → Assinatura SM2 (chave privada) → Valor da assinatura (r, s)

Usar a ferramenta do ToolsKu

  1. Abrir Ferramenta de Criptografia SM2
  2. Mudar para a aba "Assinatura"
  3. Inserir a chave privada e a mensagem a ser assinada
  4. Clicar em "Assinar" para obter o valor da assinatura

Usar JavaScript

import { sm2 } from 'sm-crypto';

const privateKey = '...';
const publicKey = '04...';

// Assinar (aplica hash SM3 automaticamente à mensagem)
const signature = sm2.doSignature('Mensagem a assinar', privateKey);
console.log('Assinatura:', signature);

// Verificar assinatura
const verified = sm2.doVerifySignature(
  'Mensagem a assinar',
  signature,
  publicKey
);
console.log('Resultado da verificação:', verified); // true

Assinatura com ID de usuário

A assinatura SM2 usa por padrão o ID de usuário 1234567812345678 (valor padrão do padrão nacional), que pode ser personalizado:

// Especificar ID de usuário ao assinar
const sig = sm2.doSignature('Mensagem', privateKey, {
  userId: 'customUserId'
});

// Usar o mesmo ID de usuário ao verificar
const valid = sm2.doVerifySignature('Mensagem', sig, publicKey, {
  userId: 'customUserId'
});

SM2 vs RSA: Quando Escolher?

Cenário Recomendação Razão
Sistemas governamentais nacionais SM2 Requisito de conformidade com padrão nacional
Sistemas financeiros nacionais SM2 Requisito da UnionPay/Banco Central
Sistemas de padrões internacionais RSA Compatibilidade internacional
Criptografia em dispositivos móveis SM2 Chave curta, cálculo rápido
Troca de dados transfronteiriça RSA Padrão internacional

Trio de Criptografia Nacional: SM2 + SM3 + SM4

Algoritmo Tipo Uso Ferramenta
SM2 Assimétrico Criptografia/Assinatura/Acordo de chaves Ferramenta SM2
SM3 Hash Resumo de mensagem (similar ao SHA-256) Ferramenta SM3
SM4 Simétrico Criptografia de dados (similar ao AES-128) Ferramenta SM4

Combinação típica: Criptografia híbrida SM2 + SM4

1. Gerar chave SM4 aleatória
2. Criptografar dados grandes com SM4 (rápido)
3. Criptografar a chave SM4 com a chave pública SM2 (transmissão segura)
4. Enviar: SM2(chave SM4) + SM4(dados)
import { sm2, sm4 } from 'sm-crypto';

// 1. Gerar chave SM4 aleatória
const sm4Key = crypto.getRandomValues(new Uint8Array(16));
const sm4KeyHex = Array.from(sm4Key).map(b => b.toString(16).padStart(2, '0')).join('');

// 2. Criptografar dados com SM4
const encryptedData = sm4.encrypt(plainText, sm4KeyHex);

// 3. Criptografar a chave SM4 com SM2
const encryptedKey = sm2.doEncrypt(sm4KeyHex, sm2PublicKey, 1);

// Enviar: encryptedKey + encryptedData

Perguntas Frequentes

Por que o texto cifrado SM2 é muito mais longo que o texto simples?

Texto cifrado SM2 = C1 (65 bytes) + C3 (32 bytes) + C2 (comprimento do texto simples), então o texto cifrado é 97 bytes mais longo que o texto simples. Esta é uma característica da criptografia assimétrica. Para dados grandes, recomenda-se criptografia híbrida SM2+SM4.

Qual é a diferença entre SM2 e ECDSA?

SM2 usa a curva elíptica especificada pelo padrão nacional (sm2p256v1), ECDSA usa curvas NIST (P-256). A lógica do algoritmo é similar, mas os parâmetros da curva são diferentes, não são compatíveis.

Como usar SM2 em Java?

// Usar Bouncy Castle + extensão de criptografia nacional
Security.addProvider(new BouncyCastleProvider());

// Gerar par de chaves
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
kpg.initialize(new ECParameterSpec(...)); // Parâmetros da curva SM2
KeyPair kp = kpg.generateKeyPair();

Resumo

SM2 é o algoritmo de criptografia assimétrica central do sistema de criptografia nacional, com uma chave de 256 bit atinge a intensidade de segurança do RSA 2048 bit. Domine as três operações principais: geração de chaves, criptografia/descriptografia e assinatura digital, junto com hash SM3 e criptografia simétrica SM4, para atender aos requisitos de conformidade do padrão nacional. O ToolsKu oferece três ferramentas online: SM2, SM3, SM4, processamento local no navegador, dados sem upload.

#国密#SM2#非对称加密#数字签名#加密教程