国密算法 SM2/SM3/SM4 原理与实践指南

国密算法 SM2/SM3/SM4 原理与实践指南

国密算法是我国自主研发的密码算法标准,由国家密码管理局制定和发布。随着网络安全形势的变化和国产密码自主可控要求的提高,国密算法在国内信息系统中的应用越来越广泛。本文详细介绍三种核心国密算法:SM2(非对称加密)、SM3(哈希算法)和 SM4(对称加密)。

一、国密算法概述

国密算法体系主要包括以下几种核心算法:

算法 类型 用途 对应国际标准
SM2 非对称加密/签名 密钥交换、数字签名 RSA/ECC
SM3 哈希算法 数据完整性校验 SHA-256
SM4 对称加密 数据加密传输 AES
SM9 标识密码 基于身份的加密

二、SM2 椭圆曲线公钥密码算法

SM2 是基于椭圆曲线的非对称密码算法,主要用于数字签名、密钥交换和公钥加密。它是我国自主设计的椭圆曲线密码算法,安全性高于 RSA。与 RSA 相比,SM2 使用更短的密钥长度即可达到相同的安全级别,例如 256 位 SM2 密钥的安全性相当于 3072 位 RSA 密钥。

算法原理

SM2 基于椭圆曲线离散对数问题(ECDLP),其核心是在有限域上的椭圆曲线上进行运算。椭圆曲线密码学的数学基础是:在椭圆曲线上,给定两个点 P 和 Q = kP(其中 k 是私钥),从 P 和 Q 计算 k 是一个困难问题,这就是椭圆曲线离散对数问题。SM2 使用的椭圆曲线参数由国家密码管理局指定,采用素域上的 Weierstrass 曲线,确保算法的安全性和合规性。

SM2 的安全性依赖于椭圆曲线离散对数问题的计算困难性。在计算上,已知椭圆曲线上的两个点 P 和 Q,找出整数 k 使得 Q = kP 是一个公认的难题,目前没有有效的多项式时间算法可以解决这个问题。

基本流程

  1. 密钥生成:生成一对公私钥,公钥公开,私钥保密
  2. 签名:使用私钥对消息进行签名
  3. 验签:使用公钥验证签名的合法性
  4. 加密:使用公钥加密数据
  5. 解密:使用私钥解密数据

前端实现示例

// SM2 key pair generation
async function generateSM2KeyPair() {
  // Use Web Crypto API or third-party library
  const keyPair = await window.crypto.subtle.generateKey(
    {
      name: 'ECDSA',
      namedCurve: 'SM2' // supported in some browsers
    },
    true,
    ['sign', 'verify']
  );
  
  return {
    publicKey: await window.crypto.subtle.exportKey('spki', keyPair.publicKey),
    privateKey: await window.crypto.subtle.exportKey('pkcs8', keyPair.privateKey)
  };
}

// SM2 sign
async function sm2Sign(privateKey, message) {
  const encoder = new TextEncoder();
  const data = encoder.encode(message);
  
  const signature = await window.crypto.subtle.sign(
    {
      name: 'ECDSA',
      hash: 'SM3'
    },
    privateKey,
    data
  );
  
  return signature;
}

// SM2 verify
async function sm2Verify(publicKey, message, signature) {
  const encoder = new TextEncoder();
  const data = encoder.encode(message);
  
  const isValid = await window.crypto.subtle.verify(
    {
      name: 'ECDSA',
      hash: 'SM3'
    },
    publicKey,
    signature,
    data
  );
  
  return isValid;
}

💡 提示:💡 提示:目前主流浏览器对 SM2 的原生支持有限,建议使用第三方库如 sm-crypto 或 gm-crypto 在前端实现国密算法。

三、SM3 密码杂凑算法

SM3 是一种密码杂凑算法(哈希函数),用于生成消息的固定长度摘要,可用于数据完整性校验和数字签名。SM3 的安全性与 SHA-256 相当,但采用了完全自主设计的压缩函数和消息扩展方式,不依赖任何国外密码标准。

算法特点

SM3 具有以下核心特点:1)单向性:给定哈希值无法还原原始消息;2)抗碰撞性:难以找到两个不同消息产生相同哈希值;3)雪崩效应:消息的微小变化会导致哈希值的巨大变化;4)固定输出:无论输入消息多长,输出都是固定的 256 位(32 字节)。

  • 输出长度:256 位(32 字节)
  • 消息分组:512 位
  • 迭代压缩:64 轮
  • 抗碰撞性:具有强抗碰撞能力

算法流程

SM3 的处理过程分为消息填充、消息扩展和压缩函数三个阶段。消息首先被填充到 512 位的倍数,然后通过消息扩展生成 68 个 32 位字,最后通过 64 轮压缩函数迭代处理,最终生成 256 位的哈希值。

  1. 消息填充:将消息填充为 512 位的倍数
  2. 消息扩展:将每个 512 位分组扩展为 132 个字
  3. 迭代压缩:对每个分组进行 64 轮压缩运算
  4. 输出摘要:输出 256 位的哈希值

前端实现示例

// Calculate SM3 using sm-crypto library
import { sm3 } from 'sm-crypto';

// Calculate SM3 hash of string
const message = 'Hello, SM3!';
const hash = sm3(message);
console.log('SM3 Hash:', hash);

// Calculate SM3 hash of byte array
const bytes = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]);
const hashBytes = sm3(bytes);
console.log('SM3 Hash (bytes):', hashBytes);

// Verify data integrity
function verifyData(original, hash) {
  const newHash = sm3(original);
  return newHash === hash;
}

四、SM4 分组密码算法

SM4 是一种分组对称密码算法,用于数据加密和解密。它采用 128 位分组和 128 位密钥,支持多种工作模式。SM4 是我国第一个公开的商用分组密码算法,具有高安全性和高效率的特点。

算法特点

SM4 具有以下核心特点:1)分组长度和密钥长度均为 128 位;2)采用非 Feistel 结构的轮函数设计;3)使用 S 盒和线性变换实现混淆和扩散;4)加密和解密使用相同的结构,只是轮密钥顺序相反;5)支持 ECB、CBC、CTR、GCM 等多种工作模式。

  • 分组长度:128 位
  • 密钥长度:128 位
  • 迭代轮数:32 轮
  • 工作模式:ECB、CBC、CFB、OFB、CTR 等

算法流程

SM4 的加密和解密过程完全相同,只是轮密钥的使用顺序相反。算法共进行 32 轮迭代,每轮使用一个轮密钥和一个非线性变换。轮密钥由原始密钥通过密钥扩展算法生成,共生成 32 个轮密钥。

  1. 密钥扩展:将 128 位密钥扩展为 32 个轮密钥
  2. 初始变换:对明文进行初始变换
  3. 轮函数变换:进行 32 轮迭代变换
  4. 逆初始变换:进行逆初始变换得到密文

前端实现示例

// SM4 encryption/decryption using sm-crypto library
import { sm4 } from 'sm-crypto';

// SM4 encryption (ECB mode)
const key = '0123456789abcdeffedcba9876543210'; // 16-byte key
const plaintext = 'Hello, SM4!';

// ECB mode encryption
const ciphertext = sm4.encrypt(plaintext, key);
console.log('SM4 ECB Ciphertext:', ciphertext);

// ECB mode decryption
const decrypted = sm4.decrypt(ciphertext, key);
console.log('SM4 ECB Decrypted:', decrypted);

// CBC mode encryption
const iv = '00000000000000000000000000000000'; // 16-byte initialization vector
const ciphertextCbc = sm4.encrypt(plaintext, key, { mode: 'cbc', iv });
console.log('SM4 CBC Ciphertext:', ciphertextCbc);

// CBC mode decryption
const decryptedCbc = sm4.decrypt(ciphertextCbc, key, { mode: 'cbc', iv });
console.log('SM4 CBC Decrypted:', decryptedCbc);

五、国密算法应用场景

1. 数字签名

数字签名是国密算法最核心的应用场景之一。在电子政务、金融交易、合同签署等领域,需要确保文档的真实性、完整性和不可否认性。使用 SM2 进行数字签名,SM3 进行哈希计算,可以有效防止文档被篡改,并提供法律上可追溯的证据。

典型应用包括:电子合同签署、电子发票验证、政务文件审批、金融交易确认等。在这些场景中,数字签名不仅保证了数据的完整性,还能提供身份认证和责任认定的功能。

const message = 'Important contract document content';

// Step 1: Calculate SM3 hash of message
const hash = sm3(message);

// Step 2: Sign hash with SM2 private key
const signature = sm2.sign(privateKey, hash);

// Step 3: Verify signature
const isValid = sm2.verify(publicKey, hash, signature);

2. 数据加密传输

数据加密传输是保护敏感数据在网络传输过程中不被窃取和篡改的重要手段。使用 SM4 对数据进行对称加密,结合 SM2 进行密钥交换,可以实现安全的数据传输。

典型应用包括:VPN 加密通道、HTTPS 加密通信、数据库加密存储、云服务数据传输等。SM4 的高效性使其特别适合大数据量的加密场景,而 SM2 的非对称特性解决了密钥分发的难题。

// Generate random SM4 key
const sm4Key = crypto.randomBytes(16).toString('hex');

// Encrypt SM4 key with SM2 public key
const encryptedKey = sm2.encrypt(publicKey, sm4Key);

// Encrypt actual data with SM4
const ciphertext = sm4.encrypt(data, sm4Key);

// Transmit encryptedKey + ciphertext
// Receiver decrypts SM4 key with SM2 private key, then decrypts data

3. 身份认证

身份认证是验证用户身份合法性的过程。使用 SM2 签名进行身份认证,可以确保用户身份的真实性,防止身份伪造和重放攻击。

典型应用包括:数字证书认证、单点登录系统、物联网设备认证、区块链身份验证等。通过国密算法实现的身份认证系统,既满足了安全性要求,又符合国内的合规标准。

// Server generates random challenge during user login
const challenge = crypto.randomBytes(32).toString('hex');

// User signs challenge with SM2 private key
const signature = sm2.sign(userPrivateKey, challenge);

// Server verifies signature with user's public key
const isValid = sm2.verify(userPublicKey, challenge, signature);

六、国密算法与国际算法对比

特性 国密算法 国际算法
非对称加密 SM2(256 位曲线) RSA(2048+ 位)/ ECC(256 位)
哈希算法 SM3(256 位) SHA-256(256 位)
对称加密 SM4(128 位) AES(128/256 位)
安全性 高,自主可控 高,但依赖国外标准
合规要求 国内强制要求 国际通用

七、实践建议

1. 选择合适的库

  • sm-crypto:轻量级国密算法库,支持 SM2/SM3/SM4
  • gm-crypto:基于 OpenSSL 的国密算法实现
  • webcrypto-core:扩展 Web Crypto API 支持国密算法

2. 密钥管理

  • 私钥必须妥善保管,避免泄露
  • 使用安全的密钥存储方案(如 Web Crypto API 的 keyUsage)
  • 定期轮换密钥

3. 模式选择

  • 对称加密优先使用 CBC 或 CTR 模式,避免 ECB
  • 每次加密使用随机的初始化向量(IV)
  • 确保 IV 的随机性和唯一性

4. 合规要求

在国内涉及敏感数据的系统中,应优先使用国密算法,满足等保合规要求。

八、总结

国密算法是我国密码学领域的重要成果,包括 SM2、SM3、SM4 三种核心算法,分别对应非对称加密、哈希和对称加密。随着国产密码自主可控要求的提高,掌握国密算法的原理和应用对于开发者来说越来越重要。

在实际开发中,应根据具体场景选择合适的算法组合,并使用成熟的第三方库来保证实现的正确性和安全性。