了解国密CCM模式示例
1 简介
CCM(Counter with CBC-MAC) 是一种认证加密模式(AEAD),同时提供:
机密性(Encryption)
完整性(Integrity)
身份认证(Authentication)
在国密体系中,CCM 通常与 SM4 分组密码结合使用,称为:
SM4-CCM
它在国标中主要用于需要同时加密和认证的通信与存储场景。

2 CCM 的设计核心
将两种成熟模式组合在一起:
CTR(计数器模式) → 用于加密
CBC-MAC → 用于认证
1️⃣ 整体结构
明文 ──CTR加密──► 密文
│
└──CBC-MAC────► 认证标签(Tag)
最终输出:
{ Nonce, Ciphertext, Authentication Tag }
设计理念:
关键设计特性
✅ 1. AEAD 一体化
同时完成:
加密
消息完整性校验
消息来源认证
避免 Encrypt-then-MAC 错误实现
✅ 2. 支持 AAD(附加认证数据)
例如:
协议头
设备 ID
版本号
不加密,但受认证保护
✅ 3. Nonce 驱动安全性
Nonce 不可重复
相同密钥 + 重复 Nonce ⇒ 灾难性安全问题
✅ 4. 可变 Tag 长度
在性能和安全性之间灵活取舍
常见:
64 bit(嵌入式)
128 bit(高安全)
3 适用场景
- 安全通信协议
国密 TLS(GM/T 0024)
VPN / 专网通信
工控协议安全封装
- 嵌入式与物联网(IoT)
MCU / 智能卡 / 安全芯片
资源受限环境
无高速乘法单元
📌 相比 GCM:
CCM 代码更小
硬件实现更简单
- 数据存储保护
安全日志
设备配置文件
传感器数据
- 国密合规系统
政务系统
金融行业
等保、密评要求系统
4 实现示例
-
服务端实现
import ( "encoding/base64" "encoding/json" "fmt" "log" "net/http" "sm4-ccm-api/internal/sm4ccm" )
全局SM4-CCM实例
var sm4Cipher *sm4ccm.SM4CCM
API请求结构
type EncryptRequest struct {
Data string `json:"data"`
}
type EncryptResponse struct {
EncryptedData string `json:"encrypted_data"`
}
type DecryptRequest struct {
EncryptedData string `json:"encrypted_data"`
}
type DecryptResponse struct {
DecryptedData string `json:"decrypted_data"`
}
初始化SM4密钥
func init() {
// 使用固定密钥或从配置文件读取
// 实际应用中应该从安全的地方获取密钥
key := []byte("1234567890abcdef") // 16字节密钥
var err error
sm4Cipher, err = sm4ccm.NewSM4CCM(key)
if err != nil {
log.Fatalf("Failed to init SM4-CCM: %v", err)
}
}
加密处理器
func encryptHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req EncryptRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
// 加密数据
ciphertext, err := sm4Cipher.Encrypt([]byte(req.Data))
if err != nil {
http.Error(w, fmt.Sprintf("Encryption failed: %v", err), http.StatusInternalServerError)
return
}
// 返回Base64编码的密文
resp := EncryptResponse{
EncryptedData: base64.StdEncoding.EncodeToString(ciphertext),
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
}
解密处理器
func decryptHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var req DecryptRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
// 解码Base64密文
ciphertext, err := base64.StdEncoding.DecodeString(req.EncryptedData)
if err != nil {
http.Error(w, "Invalid base64 data", http.StatusBadRequest)
return
}
// 解密数据
plaintext, err := sm4Cipher.Decrypt(ciphertext)
if err != nil {
http.Error(w, fmt.Sprintf("Decryption failed: %v", err), http.StatusBadRequest)
return
}
resp := DecryptResponse{
DecryptedData: string(plaintext),
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(resp)
}
func main() {
// 设置路由
http.HandleFunc("/api/encrypt", encryptHandler)
http.HandleFunc("/api/decrypt", decryptHandler)
// 健康检查
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("SM4-CCM API Server is running"))
})
port := ":8080"
log.Printf("SM4-CCM API Server starting on %s", port)
log.Printf("Endpoints:")
log.Printf(" POST /api/encrypt - Encrypt data")
log.Printf(" POST /api/decrypt - Decrypt data")
log.Printf(" GET /health - Health check")
if err := http.ListenAndServe(port, nil); err != nil {
log.Fatal(err)
}
}
-
客户端实现
import ( "bytes" "encoding/base64" "encoding/json" "fmt" "io" "log" "net/http" "sm4-ccm-api/internal/sm4ccm" "time" ) // API客户端 type SM4CCMClient struct { BaseURL string Key []byte Client *http.Client } // 请求响应结构 type EncryptRequest struct { Data string `json:"data"` } type EncryptResponse struct { EncryptedData string `json:"encrypted_data"` } type DecryptRequest struct { EncryptedData string `json:"encrypted_data"` } type DecryptResponse struct { DecryptedData string `json:"decrypted_data"` }
NewSM4CCMClient 创建客户端
func NewSM4CCMClient(baseURL string, key []byte) *SM4CCMClient {
return &SM4CCMClient{
BaseURL: baseURL,
Key: key,
Client: &http.Client{
Timeout: 30 * time.Second,
},
}
}
Encrypt 调用远程加密API
func (c *SM4CCMClient) Encrypt(data string) (string, error) {
reqBody := EncryptRequest{Data: data}
jsonData, err := json.Marshal(reqBody)
if err != nil {
return "", fmt.Errorf("marshal request failed: %v", err)
}
resp, err := c.Client.Post(c.BaseURL+"/api/encrypt", "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return "", fmt.Errorf("request failed: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return "", fmt.Errorf("API error: %s - %s", resp.Status, string(body))
}
var result EncryptResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", fmt.Errorf("parse response failed: %v", err)
}
return result.EncryptedData, nil
}
Decrypt 调用远程解密API
func (c *SM4CCMClient) Decrypt(encryptedData string) (string, error) {
reqBody := DecryptRequest{EncryptedData: encryptedData}
jsonData, err := json.Marshal(reqBody)
if err != nil {
return "", fmt.Errorf("marshal request failed: %v", err)
}
resp, err := c.Client.Post(c.BaseURL+"/api/decrypt", "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return "", fmt.Errorf("request failed: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return "", fmt.Errorf("API error: %s - %s", resp.Status, string(body))
}
var result DecryptResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", fmt.Errorf("parse response failed: %v", err)
}
return result.DecryptedData, nil
}
HealthCheck 检查服务状态
func (c *SM4CCMClient) HealthCheck() error {
resp, err := c.Client.Get(c.BaseURL + "/health")
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("health check failed: %s", resp.Status)
}
return nil
}
本地加解密(用于对比验证)
func localEncryptDecrypt(key []byte) {
cipher, err := sm4ccm.NewSM4CCM(key)
if err != nil {
log.Fatalf("Create cipher failed: %v", err)
}
// 测试数据
testData := "Hello, SM4-CCM! This is a test message. 你好,国密!"
// 本地加密
ciphertext, err := cipher.Encrypt([]byte(testData))
if err != nil {
log.Fatalf("Local encryption failed: %v", err)
}
ciphertextB64 := base64.StdEncoding.EncodeToString(ciphertext)
fmt.Printf("Local encrypted (base64): %s\n", ciphertextB64)
// 本地解密
plaintext, err := cipher.Decrypt(ciphertext)
if err != nil {
log.Fatalf("Local decryption failed: %v", err)
}
fmt.Printf("Local decrypted: %s\n", string(plaintext))
}
func main() {
// 使用与服务端相同的密钥
key := []byte("1234567890abcdef")
// 创建客户端
client := NewSM4CCMClient("http://localhost:8080", key)
// 检查服务状态
fmt.Println("Checking server health...")
if err := client.HealthCheck(); err != nil {
log.Fatalf("Health check failed: %v", err)
}
fmt.Println("Server is healthy!")
// 测试数据
testData := `{
"user_id": "12345",
"username": "张三",
"email": "zhangsan@example.com",
"sensitive_data": "This is confidential information 2024-01-15",
"timestamp": "2024-01-15T10:30:00Z"
}`
// 调用远程加密API
fmt.Println("\n=== Remote Encryption ===")
encrypted, err := client.Encrypt(testData)
if err != nil {
log.Fatalf("Remote encryption failed: %v", err)
}
fmt.Printf("Encrypted (base64): %s\n", encrypted)
// 调用远程解密API
fmt.Println("\n=== Remote Decryption ===")
decrypted, err := client.Decrypt(encrypted)
if err != nil {
log.Fatalf("Remote decryption failed: %v", err)
}
fmt.Printf("Decrypted: %s\n", decrypted)
// 验证数据一致性
if decrypted == testData {
fmt.Println("\n✓ Encryption/Decryption successful! Data matches.")
} else {
fmt.Println("\n✗ Data mismatch!")
}
// 本地加解密对比
fmt.Println("\n=== Local Encryption/Decryption ===")
localEncryptDecrypt(key)
}
-
运行说明
启动服务端:cd sm4-ccm-api go run server/main.go
启动客户端:
在另一个终端
cd sm4-ccm-api
go run client/main.go
- 测试示例
使用curl测试:
加密请求:
curl -X POST http://localhost:8080/api/encrypt \
-H "Content-Type: application/json" \
-d '{"data": "Hello, SM4-CCM!"}'
解密请求:
curl -X POST http://localhost:8080/api/decrypt \
-H "Content-Type: application/json" \
-d '{"encrypted_data": "BASE64_ENCODED_CIPHERTEXT_HERE"}'
5 小结
- 生产环境建议
密钥管理:
从环境变量或密钥管理服务获取密钥
定期轮换密钥
安全增强:
添加HTTPS支持
实现API认证(JWT、API Key等)
添加请求频率限制
性能优化:
使用连接池
添加缓存层
监控和日志:
添加详细日志
集成监控指标
这个实现提供了完整的SM4-CCM模式API服务,支持双向加解密操作,并且包含了本地和远程加解密的对比验证功能。
总体而言国密 CCM(SM4-CCM)是一种面向嵌入式和国密合规场景的高可靠 AEAD 模式,通过 CTR 加密 + CBC-MAC 认证,实现安全、可实现性和性能之间的平衡。
- 点赞
- 收藏
- 关注作者
评论(0)