了解国密加密模式CCM实现案例

举报
码乐 发表于 2026/01/11 22:24:45 2026/01/11
【摘要】 1 简介CCM (Counter with CBC-MAC), 计数器与 CBC-MAC 模式。定义:CCM 是 CTR 与 CBC-MAC 的组合,提供 AEAD 功能。工作原理:先用 CBC-MAC 计算认证标签(基于明文、AAD 和 nonce)。然后用 CTR 加密明文。加密:MAC = CBC-MAC(K, B),其中 B 是格式化的块(nonce、长度、AAD、明文);然后 C...

1 简介

CCM (Counter with CBC-MAC), 计数器与 CBC-MAC 模式。

定义:CCM 是 CTR 与 CBC-MAC 的组合,提供 AEAD 功能。

工作原理:

先用 CBC-MAC 计算认证标签(基于明文、AAD 和 nonce)。
然后用 CTR 加密明文。

加密:MAC = CBC-MAC(K, B),其中 B 是格式化的块(nonce、长度、AAD、明文);
然后 C = P \oplus CTR_stream,Tag = MAC \oplus CTR_0。
解密:验证 Tag 后解密。

优点:单密钥、提供认证、适合资源受限设备。
缺点:两次遍历数据(MAC + 加密),不如 GCM 高效;nonce 必须唯一。

安全考虑:IND-CCA2 安全,但对 nonce 长度有要求(7-13 字节)。SM4-CCM 在无线传感器网络标准中常见。
SM4 应用:IoT 设备加密、Zigbee 协议。

2 基本概念对比

CCM模式 vs SCM标准模式分析

  • 1.1 SM4标准模式

SM4标准定义了几种基础分组密码模式:

ECB (Electronic Codebook):电子密码本模式

CBC (Cipher Block Chaining):密码分组链接模式

CFB (Cipher Feedback):密码反馈模式

OFB (Output Feedback):输出反馈模式

CTR (Counter):计数器模式

这些是基础的分组密码模式,主要提供机密性。

  • 1.2 CCM模式设计

CCM加密的api项目结构

  sm4-ccm-api/
  ├── go.mod
  ├── server/
  │   └── main.go
  ├── client/
  │   └── main.go
  └── internal/
      └── sm4ccm/
          └── sm4ccm.go

3 实现案例

  1. 创建SM4-CCM加解密模块

     require github.com/tjfoc/gmsm v1.4.1
     internal/sm4ccm/sm4ccm.go:
    
     package sm4ccm
    
     import (
         "crypto/cipher"
         "crypto/rand"
         "errors"
         "fmt"
         "io"
    
         "github.com/tjfoc/gmsm/sm4"
     )
    

SM4CCM 结构体

  type SM4CCM struct {
      key []byte
  }

NewSM4CCM 创建SM4-CCM实例

    func NewSM4CCM(key []byte) (*SM4CCM, error) {
        if len(key) != 16 {
            return nil, errors.New("SM4 key must be 16 bytes")
        }
        return &SM4CCM{key: key}, nil
    }

Encrypt 加密数据 (CCM模式)

      func (s *SM4CCM) Encrypt(plaintext []byte) ([]byte, error) {
          // 创建SM4块
          block, err := sm4.NewCipher(s.key)
          if err != nil {
              return nil, fmt.Errorf("create cipher failed: %v", err)
          }

生成随机nonce (13字节推荐用于CCM)

      nonce := make([]byte, 13)
      if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
          return nil, fmt.Errorf("generate nonce failed: %v", err)
      }

创建CCM模式的AEAD

aead, err := cipher.NewCCM(block, 7, 13) // tag长度7字节,nonce长度13字节
if err != nil {
	return nil, fmt.Errorf("create CCM failed: %v", err)
}

附加数据(可以为空)

additionalData := []byte("CCM Mode")

加密

ciphertext := aead.Seal(nil, nonce, plaintext, additionalData)

返回 nonce + ciphertext

result := make([]byte, len(nonce)+len(ciphertext))
copy(result[:13], nonce)
copy(result[13:], ciphertext)

return result, nil
}

Decrypt 解密数据

    func (s *SM4CCM) Decrypt(ciphertext []byte) ([]byte, error) {
        if len(ciphertext) < 13 {
            return nil, errors.New("ciphertext too short")
        }

        block, err := sm4.NewCipher(s.key)
        if err != nil {
            return nil, fmt.Errorf("create cipher failed: %v", err)
        }

        // 创建CCM模式的AEAD
        aead, err := cipher.NewCCM(block, 7, 13)
        if err != nil {
            return nil, fmt.Errorf("create CCM failed: %v", err)
        }

        // 分离nonce和密文
        nonce := ciphertext[:13]
        actualCiphertext := ciphertext[13:]

        // 附加数据(必须与加密时一致)
        additionalData := []byte("CCM Mode")

        // 解密
        plaintext, err := aead.Open(nil, nonce, actualCiphertext, additionalData)
        if err != nil {
            return nil, fmt.Errorf("decrypt failed: %v", err)
        }

        return plaintext, nil
    }

GenerateKey 生成随机SM4密钥

  func GenerateKey() ([]byte, error) {
      key := make([]byte, 16)
      if _, err := io.ReadFull(rand.Reader, key); err != nil {
          return nil, err
      }
      return key, nil
  }

4 小结

CCM (Counter with CBC-MAC):计数器模式与CBC-MAC结合

属于认证加密模式 (Authenticated Encryption)

同时提供机密性 + 完整性认证 + 消息认

CCM vs GCM:

  • CCM: 软件实现较好,抗侧信道攻击
  • GCM: 硬件加速更好,支持流处理
  • CCM: 专利问题(已过期)
  • GCM: NIST推荐,更常用
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。