HarmonyOS鸿蒙Next开发如何对一个字符串进行sm4加密
HarmonyOS鸿蒙Next开发如何对一个字符串进行sm4加密 加密公玥已固定,假设为AAA
使用SM4算法对字符串进行加密需采用对称密钥机制(而非公钥)。根据检索信息,以下是基于C/C++的完整实现步骤(假设固定密钥"AAA"需转换为128位合法密钥):
关键步骤
-
密钥生成与转换 SM4要求128位(16字节)密钥。固定字符串"AAA"需扩展/哈希处理为16字节(示例中需自行处理转换):
// 示例:将"AAA"补全为16字节密钥(实际项目需用KDF算法) uint8_t keyData = {'A','A','A',0}; // 简单补零,仅演示 -
创建Cipher实例 根据分组模式选择初始化参数(此处以CBC模式为例):
// 创建SM4_CBC_PKCS7模式的Cipher OH_CryptoSymCipher* cipher = nullptr; OH_CryptoSymCipher_Create("SM4_128|CBC|PKCS7", &cipher); -
设置加密参数
OH_CryptoSymCipherParams* params = nullptr; OH_CryptoSymCipherParams_Create(¶ms); // 设置IV(CBC模式必需) uint8_t iv = {0}; // 示例IV,实际需用随机值 OH_CryptoSymCipherParams_SetParam(params, "iv", iv, sizeof(iv)); -
执行加密
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 -
资源释放
OH_CryptoSymCipher_Destroy(cipher); OH_CryptoSymCipherParams_Destroy(params);
更多关于HarmonyOS鸿蒙Next开发如何对一个字符串进行sm4加密的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
兄弟,使用SM4算法对字符串进行加密需遵循以下步骤(以CBC模式为例):
核心流程
- 生成SM4对称密钥 123 密钥长度需为128位,通过
cryptoFramework.createSymKeyGenerator创建密钥生成器:
let symGenerator = cryptoFramework.createSymKeyGenerator('SM4_128');
let symKey = await symGenerator.convertKey(symKeyBlob); // symKeyBlob为Uint8Array格式密钥数据
- 初始化加密参数(IV) 1 CBC模式需16字节初始化向量:
function genIvParamsSpec() {
let ivBlob = generateRandom(16); // 生成16字节随机IV
return { algName: "IvParamsSpec", iv: ivBlob };
}
let iv = genIvParamsSpec();
- 创建Cipher实例
指定算法为
SM4_128|CBC|PKCS7:
let cipher = cryptoFramework.createCipher('SM4_128|CBC|PKCS7');
- 执行加密操作
- 初始化加密模式
- 将字符串转为
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;
}
关键要点:
-
密钥长度: SM4要求密钥长度为128位(16字节),你的"AAA"字符串只有3字节,需要填充到16字节
-
加密模式选择:
- ECB模式 (crypto-sm4-sym-encrypt-decrypt-ecb.md:52): 最简单,无需IV向量,适合短数据
- CBC模式 (crypto-sm4-sym-encrypt-decrypt-cbc.md:65): 更安全,需要16字节IV向量
- GCM模式: 提供认证加密,最安全但更复杂
-
算法字符串格式: ‘SM4_128|模式|填充’
- 例如: ‘SM4_128|ECB|PKCS7’ 或 ‘SM4_128|CBC|PKCS7’
-
导入模块:
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';
- 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}`);
});
注意事项:
- 密钥需要是16字节(128位),示例中将"AAA"通过补零扩展为16字节
- 实际生产环境应使用安全的密钥生成方式
- ECB模式适用于简单场景,敏感数据建议使用CBC等更安全的模式
- 需在module.json5中添加加密权限:
"requestPermissions": ["ohos.permission.USE_CRYPTO"]
此代码实现了基本的SM4-ECB加密,返回Base64格式的密文。

