SM2 国密签名验签
国密 SM2 椭圆曲线公钥密码算法 · 严格遵循
GB/T 32918-2016 /
GM/T 0003-2012 商用密码标准 · 256 位曲线 · 数字签名与验签
SM2 签名规范要求,默认值 16 字节
字符数: 0 | 字节数: 0
长度: 0 字符
代码示例(SM2 签名/验签/加解密)
// npm install sm-crypto
const sm2 = require('sm-crypto').sm2;
// 1) 生成密钥对
const keypair = sm2.generateKeyPairHex();
console.log('私钥:', keypair.privateKey); // 64 hex
console.log('公钥:', keypair.publicKey); // 130 hex (04+x+y)
// 2) 签名 (der 编码: 0)
const msg = 'hello 国密';
const sigHex = sm2.doSignature(msg, keypair.privateKey, {
hash: true, // 内部先 SM3 摘要
userId: '1234567812345678'
});
// 3) 验签
const ok = sm2.doVerifySignature(msg, sigHex, keypair.publicKey, {
hash: true,
userId: '1234567812345678'
});
console.log('验签:', ok);
// 4) 加密 (C1C3C2 = cipherMode 1)
const cipher = sm2.doEncrypt(msg, keypair.publicKey, 1);
const plain = sm2.doDecrypt(cipher, keypair.privateKey, 1);
console.log('解密:', plain);
// BouncyCastle SM2
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.math.ec.ECPoint;
// 生成密钥对
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "BC");
ECGenParameterSpec spec = new ECGenParameterSpec("sm2p256v1");
kpg.initialize(spec);
KeyPair kp = kpg.generateKeyPair();
// 签名
SM2Signer signer = new SM2Signer();
signer.init(true, new ParametersWithID(privKeyParams, userId));
signer.update(msg, 0, msg.length);
byte[] sig = signer.generateSignature();
// 验签
signer.init(false, new ParametersWithID(pubKeyParams, userId));
signer.update(msg, 0, msg.length);
boolean ok = signer.verifySignature(sig);
# pip install gmssl
from gmssl import sm2
# 密钥对(Hex)
private_key = '00B9AB0B828FF68872F21A837FC303668428DEA11DCD1B24429D0C99E24EED83D5'
public_key = '...' # 04 开头 130 hex
sm2_crypt = sm2.CryptSM2(
private_key=private_key,
public_key=public_key
)
# 签名
msg = b'hello'
sig = sm2_crypt.sign(msg, '1234567812345678'.encode())
print('签名:', sig)
# 验签
ok = sm2_crypt.verify(sig, msg)
print('验签:', ok)
# 加密/解密
cipher = sm2_crypt.encrypt(msg)
plain = sm2_crypt.decrypt(cipher)
print('解密:', plain)
package main
import (
"crypto/rand"
"encoding/hex"
"fmt"
"github.com/tjfoc/gmsm/sm2"
)
func main() {
// 生成密钥对
priv, _ := sm2.GenerateKey(rand.Reader)
pub := &priv.PublicKey
// 签名
msg := []byte("hello 国密")
uid := []byte("1234567812345678")
sig, _ := priv.SignWithSM2(rand.Reader, uid, msg)
fmt.Println("签名:", hex.EncodeToString(sig))
// 验签
ok := pub.VerifyWithSM2(msg, uid, sig)
fmt.Println("验签:", ok)
// 加密/解密
cipher, _ := sm2.Encrypt(pub, msg, rand.Reader, sm2.C1C3C2)
plain, _ := sm2.Decrypt(priv, cipher, sm2.C1C3C2)
fmt.Println("解密:", string(plain))
}
SM2 算法说明
| 参数 | 说明 |
|---|---|
| 标准 | GB/T 32918-2016 / GM/T 0003-2012 国家密码管理局 |
| 曲线 | sm2p256v1 (256 位素域椭圆曲线) |
| 私钥 | 256 位随机整数 (64 Hex 字符) |
| 公钥 | 曲线上的点 (x, y),非压缩格式 04+X+Y (130 Hex) |
| 签名输出 | (r, s) 各 256 位,DER 编码或裸拼接 |
| 加密输出 | C1 (65字节椭圆曲线点) + C3 (32字节SM3摘要) + C2 (密文) |
| 哈希函数 | SM3 (国标强制) |
| 用户 ID | 签名时参与 Z 值计算,默认 "1234567812345678" |
| 典型应用 | 电子签名、身份认证、SSL/TLS 国密套件、区块链、电子发票 |
