Guide complet du chiffrement SM2 : génération de clés, chiffrement, déchiffrement et signature numérique en pratique
Qu'est-ce que SM2 ?
SM2 est un algorithme de chiffrement asymétrique publié par l'Administration nationale de cryptographie de Chine, basé sur la cryptographie sur courbes elliptiques (ECC), remplaçant RSA comme norme nationale.
| Comparaison | SM2 | RSA 2048 |
|---|---|---|
| Longueur de clé | 256 bits | 2048 bits |
| Niveau de sécurité | 128 bits | 112 bits |
| Vitesse de signature | ~0,5ms | ~3ms |
| Vitesse de vérification | ~1ms | ~0,1ms |
| Ratio de longueur de clé | 1 | 8 |
| Norme nationale | GM/T 0003 | PKCS#1 |
SM2 atteint le niveau de sécurité de RSA 2048 bits avec une clé de 256 bits, clé plus courte, vitesse plus rapide.
Trois usages de SM2
| Usage | Description | Outil correspondant |
|---|---|---|
| Chiffrement/Déchiffrement | Chiffrer avec la clé publique, déchiffrer avec la clé privée | Chiffrement SM2 |
| Signature numérique | Signer avec la clé privée, vérifier avec la clé publique | Signature SM2 |
| Négociation de clés | Les deux parties négocient une clé partagée | Protocole ECDH |
Étape 1 : Générer une paire de clés SM2
Utiliser l'outil ToolsKu
- Ouvrir l'outil de chiffrement SM2
- Cliquer sur « Générer une paire de clés »
- Obtenir la clé publique et la clé privée
Utiliser la ligne de commande
# Installer gmssl
brew install gmssl # macOS
# Ou télécharger depuis https://github.com/guanzhi/GmSSL/releases
# Générer une paire de clés SM2
gmssl sm2 -genkey -out sm2.key
# Afficher les clés
gmssl sm2 -in sm2.key -text
Utiliser JavaScript
import { sm2 } from 'sm-crypto';
// Générer une paire de clés
const keyPair = sm2.generateKeyPairHex();
// keyPair.privateKey → clé privée (64 hexadécimales)
// keyPair.publicKey → clé publique (128 hexadécimales, 04 + X + Y)
console.log('Clé privée :', keyPair.privateKey);
console.log('Clé publique :', keyPair.publicKey);
Format de clé
Format de clé publique SM2 :
04 || X (32 octets) || Y (32 octets)
↓
04 + 64 hexadécimales X + 64 hexadécimales Y
Longueur totale : 130 caractères hexadécimaux (65 octets)
Format de clé privée SM2 :
Nombre aléatoire de 32 octets
Longueur totale : 64 caractères hexadécimaux (32 octets)
Étape 2 : Chiffrement et déchiffrement SM2
Processus de chiffrement
Texte clair → Chiffrement SM2 (clé publique) → Texte chiffré (C1 || C3 || C2)
- C1 : Point de courbe elliptique (65 octets)
- C3 : Hash SM3 (32 octets)
- C2 : Données chiffrées
Utiliser l'outil ToolsKu
- Ouvrir l'outil de chiffrement SM2
- Coller la clé publique
- Saisir le texte clair à chiffrer
- Sélectionner le format du texte chiffré (C1C3C2 ou C1C2C3)
- Cliquer sur « Chiffrer » pour obtenir le texte chiffré
Utiliser JavaScript
import { sm2 } from 'sm-crypto';
const publicKey = '04...'; // 128 hexadécimales
const privateKey = '...'; // 64 hexadécimales
// Chiffrer (format C1C3C2 par défaut)
const cipherText = sm2.doEncrypt('Bonjour SM2', publicKey, 1);
// Paramètre 1 = format C1C3C2 (recommandé par la norme nationale)
// Paramètre 0 = format C1C2C3 (compatibilité ancienne version)
console.log('Texte chiffré :', cipherText);
// Déchiffrer
const plainText = sm2.doDecrypt(cipherText, privateKey, 1);
console.log('Texte clair :', plainText); // "Bonjour SM2"
Formats d'encodage du texte chiffré
| Format | Description | Scénario d'usage |
|---|---|---|
| C1C3C2 | Format recommandé par la norme nationale | Nouveaux projets (par défaut) |
| C1C2C3 | Format ancienne version | Compatibilité avec les anciens systèmes |
| ASN.1 | Encodage DER | Interopérabilité Java/C# |
Étape 3 : Signature numérique SM2
Processus de signature
Message → Hash SM3 → Signature SM2 (clé privée) → Valeur de signature (r, s)
Utiliser l'outil ToolsKu
- Ouvrir l'outil de chiffrement SM2
- Passer à l'onglet « Signature »
- Saisir la clé privée et le message à signer
- Cliquer sur « Signer » pour obtenir la valeur de signature
Utiliser JavaScript
import { sm2 } from 'sm-crypto';
const privateKey = '...';
const publicKey = '04...';
// Signer (hash SM3 automatique du message)
const signature = sm2.doSignature('Message à signer', privateKey);
console.log('Signature :', signature);
// Vérifier la signature
const verified = sm2.doVerifySignature(
'Message à signer',
signature,
publicKey
);
console.log('Résultat de vérification :', verified); // true
Signature avec ID utilisateur
La signature SM2 utilise par défaut l'ID utilisateur 1234567812345678 (valeur par défaut de la norme nationale), qui peut être personnalisé :
// Spécifier l'ID utilisateur lors de la signature
const sig = sm2.doSignature('Message', privateKey, {
userId: 'customUserId'
});
// Utiliser le même ID utilisateur lors de la vérification
const valid = sm2.doVerifySignature('Message', sig, publicKey, {
userId: 'customUserId'
});
SM2 vs RSA : Quand choisir ?
| Scénario | Recommandation | Raison |
|---|---|---|
| Systèmes gouvernementaux nationaux | SM2 | Exigence de conformité à la norme nationale |
| Systèmes financiers nationaux | SM2 | Exigence UnionPay/Banque populaire |
| Systèmes de normes internationales | RSA | Compatibilité internationale |
| Chiffrement mobile | SM2 | Clé courte, calcul rapide |
| Échange de données transfrontalier | RSA | Norme internationale |
Trio de cryptographie nationale : SM2 + SM3 + SM4
| Algorithme | Type | Usage | Outil |
|---|---|---|---|
| SM2 | Asymétrique | Chiffrement/Signature/Négociation de clés | Outil SM2 |
| SM3 | Hash | Résumé de message (similaire à SHA-256) | Outil SM3 |
| SM4 | Symétrique | Chiffrement de données (similaire à AES-128) | Outil SM4 |
Combinaison typique : Chiffrement hybride SM2 + SM4
1. Générer une clé SM4 aléatoire
2. Chiffrer les données volumineuses avec SM4 (rapide)
3. Chiffrer la clé SM4 avec la clé publique SM2 (transmission sécurisée)
4. Envoyer : SM2(clé SM4) + SM4(données)
import { sm2, sm4 } from 'sm-crypto';
// 1. Générer une clé SM4 aléatoire
const sm4Key = crypto.getRandomValues(new Uint8Array(16));
const sm4KeyHex = Array.from(sm4Key).map(b => b.toString(16).padStart(2, '0')).join('');
// 2. Chiffrer les données avec SM4
const encryptedData = sm4.encrypt(plainText, sm4KeyHex);
// 3. Chiffrer la clé SM4 avec SM2
const encryptedKey = sm2.doEncrypt(sm4KeyHex, sm2PublicKey, 1);
// Envoyer : encryptedKey + encryptedData
Questions fréquentes
Pourquoi le texte chiffré SM2 est-il beaucoup plus long que le texte clair ?
Texte chiffré SM2 = C1 (65 octets) + C3 (32 octets) + C2 (longueur du texte clair), donc le texte chiffré est 97 octets plus long que le texte clair. C'est une caractéristique du chiffrement asymétrique. Pour les données volumineuses, le chiffrement hybride SM2+SM4 est recommandé.
Quelle est la différence entre SM2 et ECDSA ?
SM2 utilise la courbe elliptique spécifiée par la norme nationale (sm2p256v1), ECDSA utilise les courbes NIST (P-256). La logique de l'algorithme est similaire, mais les paramètres de la courbe sont différents, ils ne sont pas compatibles.
Comment utiliser SM2 en Java ?
// Utiliser Bouncy Castle + extension de cryptographie nationale
Security.addProvider(new BouncyCastleProvider());
// Générer une paire de clés
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
kpg.initialize(new ECParameterSpec(...)); // Paramètres de courbe SM2
KeyPair kp = kpg.generateKeyPair();
Résumé
SM2 est l'algorithme de chiffrement asymétrique central du système de cryptographie nationale, atteignant le niveau de sécurité de RSA 2048 bits avec une clé de 256 bits. Maîtrisez les trois opérations principales : génération de clés, chiffrement/déchiffrement et signature numérique, combinées au hash SM3 et au chiffrement symétrique SM4, pour répondre aux exigences de conformité de la norme nationale. ToolsKu propose trois outils en ligne : SM2, SM3, SM4, traitement local dans le navigateur, aucune donnée téléchargée.