Guia Completo de Criptografia SM2: Geração de Chaves, Criptografia, Descriptografia e Assinatura Digital na Prática
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
- Abrir Ferramenta de Criptografia SM2
- Clicar em "Gerar par de chaves"
- 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
- Abrir Ferramenta de Criptografia SM2
- Colar a chave pública
- Inserir o texto simples a ser criptografado
- Selecionar o formato do texto cifrado (C1C3C2 ou C1C2C3)
- 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
- Abrir Ferramenta de Criptografia SM2
- Mudar para a aba "Assinatura"
- Inserir a chave privada e a mensagem a ser assinada
- 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.