Skip to content

SM4 加解密

SM4 是国密对称加密算法,GMSm4Utils 提供了其 Objective-C 实现。支持 ECB 和 CBC 两种加密模式,可用于加密二进制数据或字符串。

特性介绍

  • 分组大小: 16 字节
  • 密钥长度: 16 字节(HEX 编码时为 32 字符)
  • 填充方式: PKCS7Padding(自动补齐到 16 字节的倍数)
  • 加密模式:
    • ECB (电子密码本模式): 将明文按照固定的块大小(16 字节)进行分割(不足补齐),逐个块加密。
    • CBC (密文分组链接模式): 每个明文块先与前一个密文块进行异或操作再加密,需要 16 字节的初始向量(IV),安全性更高。

密钥生成

objc
// 生成 32 字符的 HEX 格式密钥。输出示例: CCDEE6FB253E1CBCD40B12D5E230D0F4
NSString *key = [GMSm4Utils generateKey];

ECB 模式

注意

密钥格式要求:

  • 字符串模式:32 字符的 HEX 字符串
  • 二进制模式:16 字节的 NSData

二进制数据处理

objc
// 1. 字符串加密(使用 HEX 格式的密钥)
NSString *sm4KeyHex = @"CCDEE6FB253E1CBCD40B12D5E230D0F4";
NSString *plaintext = @"Hello, SM4!";
// 加密。密文为 HEX 编码格式
NSString *cipherHex = [GMSm4Utils encryptTextWithECB:plaintext keyHex:sm4KeyHex];
// 解密。解密结果为 "Hello, SM4!"
NSString *decrypted = [GMSm4Utils decryptTextWithECB:cipherHex keyHex:sm4KeyHex];

// 2. 二进制数据加密
// 将 HEX 格式密钥转换为 NSData
NSData *sm4KeyData = [GMSmUtils dataFromHexString:sm4KeyHex];
// 或直接使用 16 字节字符串转 NSData
// NSData *sm4KeyData = [@"0123456789abcdef" dataUsingEncoding:NSUTF8StringEncoding];

NSData *plainData = [@"123456" dataUsingEncoding:NSUTF8StringEncoding];
// 加密
NSData *cipherData = [GMSm4Utils encryptDataWithECB:plainData keyData:sm4KeyData];
// 解密
NSData *decrypted = [GMSm4Utils decryptDataWithECB:cipherData keyData:sm4KeyData];

CBC 模式

注意事项

  • 密钥和 IV 都必须是 16 字节长度(HEX 编码的密钥/IV 长度为 32 字节)。
  • 加解密必须使用相同的 IV,IV 向量可以看做一个固定长度的随机数。
  • CBC 模式比 ECB 更安全,推荐用于敏感数据加密。
objc
// 1. 字符串加密(使用 HEX 格式的密钥和 IV)
NSString *sm4KeyHex = @"CCDEE6FB253E1CBCD40B12D5E230D0F4";
NSString *ivecHex = @"CCDEE6FB253E1CBCD40B12D5E230D0F4";
NSString *plaintext = @"Hello, SM4!";
// 加密。输出 HEX 格式密文
NSString *ciphertext = [GMSm4Utils encryptTextWithCBC:plaintext keyHex:sm4KeyHex ivecHex:ivecHex];
// 解密。解密结果为 "Hello, SM4!"
NSString *decrypted = [GMSm4Utils decryptTextWithCBC:ciphertext keyHex:sm4KeyHex ivecHex:ivecHex];

// 2. 二进制数据加密
// 将 HEX 格式密钥和 IV 转换为 NSData
NSData *sm4KeyData = [GMSmUtils dataFromHexString:sm4KeyHex];
NSData *ivecData = [GMSmUtils dataFromHexString:ivecHex];
// 或直接使用 16 字节字符串转 NSData
// NSData *sm4KeyData = [@"0123456789abcdef" dataUsingEncoding:NSUTF8StringEncoding];
// NSData *ivecData = [@"0123456789abcdef" dataUsingEncoding:NSUTF8StringEncoding];

NSData *plainData = [@"123456" dataUsingEncoding:NSUTF8StringEncoding];
// 加密
NSData *cipherData = [GMSm4Utils encryptDataWithCBC:plainData keyData:sm4KeyData ivecData:ivecData];
// 解密
NSData *decrypted = [GMSm4Utils decryptDataWithCBC:cipherData keyData:sm4KeyData ivecData:ivecData];

基于 MIT 许可发布