HarmonyOS鸿蒙Next开发如何对一个字符串进行sm4加密

HarmonyOS鸿蒙Next开发如何对一个字符串进行sm4加密 加密公玥已固定,假设为AAA

7 回复

使用SM4算法对字符串进行加密需采用对称密钥机制(而非公钥)。根据检索信息,以下是基于C/C++的完整实现步骤(假设固定密钥"AAA"需转换为128位合法密钥):


关键步骤

  1. 密钥生成与转换 SM4要求128位(16字节)密钥。固定字符串"AAA"需扩展/哈希处理为16字节(示例中需自行处理转换):

    // 示例:将"AAA"补全为16字节密钥(实际项目需用KDF算法)
    uint8_t keyData = {'A','A','A',0}; // 简单补零,仅演示
    
  2. 创建Cipher实例 根据分组模式选择初始化参数(此处以CBC模式为例):

    // 创建SM4_CBC_PKCS7模式的Cipher
    OH_CryptoSymCipher* cipher = nullptr;
    OH_CryptoSymCipher_Create("SM4_128|CBC|PKCS7", &cipher);
    
  3. 设置加密参数

    OH_CryptoSymCipherParams* params = nullptr;
    OH_CryptoSymCipherParams_Create(&params);
    
    // 设置IV(CBC模式必需)
    uint8_t iv = {0}; // 示例IV,实际需用随机值
    OH_CryptoSymCipherParams_SetParam(params, "iv", iv, sizeof(iv));
    
  4. 执行加密

    const char* plainText = "Hello HarmonyOS";
    size_t plainLen = strlen(plainText);
    
    // 初始化加密
    OH_CryptoSymCipher_Init(cipher, OH_CRYPTO_MODE_ENCRYPT, keyCtx, params);
    
    // 分段更新数据
    OH_CryptoBlob input = { reinterpret_cast<uint8_t*>(plainText), plainLen };
    OH_CryptoBlob output;
    OH_CryptoSymCipher_Update(cipher, &input, &output);
    
    // 获取最终密文
    OH_CryptoBlob finalOutput;
    OH_CryptoSymCipher_Final(cipher, nullptr, &finalOutput); // data传null
    
    // 密文存储在finalOutput.data中,长度为finalOutput.size
    
  5. 资源释放

    OH_CryptoSymCipher_Destroy(cipher);
    OH_CryptoSymCipherParams_Destroy(params);
    

更多关于HarmonyOS鸿蒙Next开发如何对一个字符串进行sm4加密的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


兄弟,使用SM4算法对字符串进行加密需遵循以下步骤(以CBC模式为例):

核心流程

  1. 生成SM4对称密钥 123 密钥长度需为128位,通过cryptoFramework.createSymKeyGenerator创建密钥生成器:
let symGenerator = cryptoFramework.createSymKeyGenerator('SM4_128');
let symKey = await symGenerator.convertKey(symKeyBlob); // symKeyBlob为Uint8Array格式密钥数据
  1. 初始化加密参数(IV) 1 CBC模式需16字节初始化向量:
function genIvParamsSpec() {
  let ivBlob = generateRandom(16); // 生成16字节随机IV
  return { algName: "IvParamsSpec", iv: ivBlob };
}
let iv = genIvParamsSpec();
  1. 创建Cipher实例 指定算法为SM4_128|CBC|PKCS7
let cipher = cryptoFramework.createCipher('SM4_128|CBC|PKCS7');
  1. 执行加密操作
    • 初始化加密模式
    • 将字符串转为DataBlob
    • 调用doFinal加密
// 字符串转DataBlob
let message = "待加密字符串";
let plainText: cryptoFramework.DataBlob = { 
  new Uint8Array(buffer.from(message, 'utf-8').buffer) 
};

// 加密执行
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv);
let encryptData = await cipher.doFinal(plainText); // 输出加密后的DataBlob

完整异步示例

import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';

// 生成IV(16字节)
function generateRandom(len: number) {
  let rand = cryptoFramework.createRandom();
  return rand.generateRandomSync(len);
}
function genIvParamsSpec() {
  let ivBlob = generateRandom(16);
  return { algName: "IvParamsSpec", iv: ivBlob };
}

// 加密函数
async function encryptString(symKey: cryptoFramework.SymKey, plainText: string) {
  let iv = genIvParamsSpec();
  let cipher = cryptoFramework.createCipher('SM4_128|CBC|PKCS7');
  
  // 初始化加密模式
  await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv);
  
  // 字符串转DataBlob
  let textBlob: cryptoFramework.DataBlob = {
    new Uint8Array(buffer.from(plainText, 'utf-8').buffer)
  };
  
  // 执行加密
  return await cipher.doFinal(textBlob);
}

// 使用示例
async function main() {
  try {
    // 密钥数据(示例值,实际需替换)
    let keyData = new Uint8Array([7, 154, 52, 176, 4, 236, 150, 43, 237, 9, 145, 166, 141, 174, 224, 131]);
    
    // 生成密钥
    let symGenerator = cryptoFramework.createSymKeyGenerator('SM4_128');
    let symKeyBlob: cryptoFramework.DataBlob = { keyData };
    let symKey = await symGenerator.convertKey(symKeyBlob);
    
    // 加密字符串
    let encryptResult = await encryptString(symKey, "Hello HarmonyOS");
    console.info('加密结果:', encryptResult.data);
  } catch (error) {
    console.error(`SM4加密失败: ${error.code}, ${error.message}`);
  }
}

这里有一个封装好的第三方库,都是调用的鸿蒙的api实现的:

网址:[https://ohpm.openharmony.cn/#/cn/detail/@yunkss%2Fef_crypto](https://ohpm.openharmony.cn/#/cn/detail/@yunkss%2Fef_crypto)

SM4的方法:

  • generateSM4Key 生成SM4的对称密钥
let sm4 = await SM4.generateSM4Key();
console.error("密钥======:", sm4);
  • encodeECB 加密-ECB模式
let encodeECB = await SM4.encodeECB('测试SM4加密字符串Test!', sm4);
this.message = encodeECB;
  • decodeECB 解密-ECB模式
let decodeECB = await SM4.decodeECB(encodeECB, sm4);
this.message = decodeECB;
  • encodeCBC 加密-CBC模式 需要传入iv偏移量字符串(IV生成详见@yunkss/ef_core下的RandomUtil)
let encodeCBC = await SM4.encodeCBC('测试SM4的CBC加密字符串Test!', sm4, iv);
this.message = encodeCBC;
  • decodeCBC 解密-CBC模式 需要传入iv偏移量字符串(IV生成详见@yunkss/ef_core下的RandomUtil)
let decodeCBC = await SM4.decodeCBC(encodeCBC, sm4, iv);
this.message = decodeCBC;

HarmonyOS的分布式文件系统让我在多设备间共享文件变得更加方便。

鸿蒙SM4加密字符串方法

使用固定密钥"AAA"进行加密的示例:

import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';

// 将字符串密钥"AAA"转换为16字节的密钥数据(SM4需要128位=16字节)

function generateKeyFromString(keyString: string): Uint8Array {
  // 方式1: 将字符串填充或截断到16字节
  let keyData = new Uint8Array(16);
  let strBytes = buffer.from(keyString, 'utf-8');
  for (let i = 0; i < Math.min(strBytes.length, 16); i++) {
    keyData[i] = strBytes[i];
  }
  return keyData;
}

// 从密钥数据生成SM4对称密钥
async function genSymKeyByData(symKeyData: Uint8Array) {
  let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
  let symGenerator = cryptoFramework.createSymKeyGenerator('SM4_128');
  let symKey = await symGenerator.convertKey(symKeyBlob);
  console.info('convertKey success');
  return symKey;
}

// 加密字符串
async function encryptString(plainString: string, keyString: string = "AAA") {
  // 生成密钥
  let keyData = generateKeyFromString(keyString);
  let symKey = await genSymKeyByData(keyData);
  // 准备待加密的字符串
  let plainText: cryptoFramework.DataBlob = {
    data: new Uint8Array(buffer.from(plainString, 'utf-8').buffer)
  };
  // 创建SM4加密器 (ECB模式)
  let cipher = cryptoFramework.createCipher('SM4_128|ECB|PKCS7');
  // 初始化加密器
  await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null);
  // 执行加密
  let encryptData = await cipher.doFinal(plainText);
  return encryptData;
}

// 使用示例
async function main() {
  let message = "Hello, HarmonyOS!";
  let encryptedData = await encryptString(message, "AAA");
  // 输出加密结果(可以转为Base64或Hex格式)
  console.info('Encrypted data length: ' + encryptedData.data.length);
  console.info('Encrypted data: ' + buffer.from(encryptedData.data).toString('base64'));
}

同步方法版本(推荐用于简单场景):
function encryptStringSync(plainString: string, keyString: string = "AAA") {
  // 生成密钥数据
  let keyData = generateKeyFromString(keyString);
  let symKeyBlob: cryptoFramework.DataBlob = { data: keyData };
  let symGenerator = cryptoFramework.createSymKeyGenerator('SM4_128');
  let symKey = symGenerator.convertKeySync(symKeyBlob);
  // 准备明文
  let plainText: cryptoFramework.DataBlob = {
    data: new Uint8Array(buffer.from(plainString, 'utf-8').buffer)
  };
  // 创建加密器并加密
  let cipher = cryptoFramework.createCipher('SM4_128|ECB|PKCS7');
  cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null);
  let encryptData = cipher.doFinalSync(plainText);
  return encryptData;
}

关键要点:

  1. 密钥长度: SM4要求密钥长度为128位(16字节),你的"AAA"字符串只有3字节,需要填充到16字节

  2. 加密模式选择:

  3. 算法字符串格式: ‘SM4_128|模式|填充’

    • 例如: ‘SM4_128|ECB|PKCS7’ 或 ‘SM4_128|CBC|PKCS7’
  4. 导入模块:

import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';
  1. API文档:
    • ECB模式: crypto-sm4-sym-encrypt-decrypt-ecb
    • CBC模式: crypto-sm4-sym-encrypt-decrypt-cbc

在HarmonyOS鸿蒙Next中,使用@ohos.security.cryptoLib模块进行SM4加密。首先导入cryptoLib,创建对称密钥生成器cryptoFramework.createSymKeyGenerator('SM4_128')。通过convertKey生成密钥对象。使用cryptoFramework.createCipher('SM4_128|ECB|PKCS7')创建加密器,调用init设置加密模式和密钥。输入字符串需转为Unit8Array格式,执行doFinal完成加密,输出为Unit8Array数据。全程使用鸿蒙原生API,无需依赖外部库。

在HarmonyOS Next中,可以使用SM4加密算法对字符串进行加密。以下是一个基于ArkTS的示例代码:

import { cryptoFramework } from '@kit.CryptoArchitectureKit';

// 固定密钥(示例中为"AAA",实际使用时需要转换为16字节的十六进制格式)
const KEY_STRING = '41414100000000000000000000000000'; // "AAA"补齐为16字节

async function sm4Encrypt(plainText: string): Promise<string> {
  try {
    // 1. 创建SM4实例
    const sm4Cipher = cryptoFramework.createCipher('SM4_128_ECB');

    // 2. 准备密钥
    const keyBlob = { data: KEY_STRING };
    const symKeyGenerator = cryptoFramework.createSymKeyGenerator('SM4');
    const key = await symKeyGenerator.convertKey(keyBlob);

    // 3. 初始化并执行加密
    await sm4Cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, key, null);
    const input = { data: plainText, encoding: 'utf-8' };
    const output = await sm4Cipher.doFinal(input);

    // 4. 返回Base64编码结果
    return output.data;
  } catch (error) {
    console.error(`SM4加密失败: ${error.message}`);
    throw error;
  }
}

// 使用示例
const originalString = 'Hello HarmonyOS';
sm4Encrypt(originalString).then(encryptedText => {
  console.log(`加密结果: ${encryptedText}`);
});

注意事项:

  1. 密钥需要是16字节(128位),示例中将"AAA"通过补零扩展为16字节
  2. 实际生产环境应使用安全的密钥生成方式
  3. ECB模式适用于简单场景,敏感数据建议使用CBC等更安全的模式
  4. 需在module.json5中添加加密权限:"requestPermissions": ["ohos.permission.USE_CRYPTO"]

此代码实现了基本的SM4-ECB加密,返回Base64格式的密文。

回到顶部