cryptoFramework
简介
cryptoFramework 是鸿蒙(HarmonyOS/OpenHarmony)中功能全面的原生加解密框架,它统一了底层密码库的差异,为开发者提供了进行加解密等安全操作的接口。
为了帮助你快速了解这个框架的核心,我整理了它的主要功能、关键模块和开发须知:
| 模块/功能 | 说明 |
|---|---|
| 框架定位 | 统一第三方密码库差异,提供通用加解密功能的算法框架。 |
| 核心能力 | 支持加解密、签名验签、哈希、安全随机数、密钥派生等多种功能。 |
| 关键限制 | 1. 仅负责密钥运算,不管理密钥存储 。如需密钥管理,需结合 Universal Keystore Kit (HUKS)。 2. 不支持多线程并发操作 。 3. 部分算法(如MD5)不适用于高安全场景。 |
| 常用模块 | Cipher : 用于加解密。 Sign/Verify : 用于签名验签。 Md : 用于计算消息摘要。 Random : 用于生成安全随机数。 SymKeyGenerator/AsyKeyGenerator: 用于生成对称/非对称密钥。 |
基本开发步骤与示例
以下是使用 cryptoFramework 进行 MD5 哈希计算的典型代码示例,展示了其基本调用模式:
TypeScript
import { cryptoFramework } from '@kit.CryptoArchitectureKit'; // API 11+ 推荐导入方式[citation:8]
// 或使用:import cryptoFramework from '@ohos.security.cryptoFramework'; // API 9 及更早版本
async function computeMD5(message: string): Promise<string> {
// 1. 创建算法实例
let md = cryptoFramework.createMd('MD5');
// 2. 准备数据(需转换为DataBlob格式)
let dataBlob: cryptoFramework.DataBlob = { data: new TextEncoder().encode(message) };
// 3. 执行计算(异步)
let digest: cryptoFramework.DataBlob = await md.digest(dataBlob);
// 4. 处理结果(转换为十六进制字符串)
return Array.from(new Uint8Array(digest.data)).map(b => b.toString(16).padStart(2, '0')).join('');
}
实践建议与资源
-
算法选型:
-
对称加密 :推荐 AES-GCM,它同时提供机密性和完整性。
-
哈希算法 :避免在不安全的场景下单独使用MD5 ,推荐使用SHA-256等更安全的算法。
-
填充模式 :使用
NoPadding时需自行处理明文长度;直接使用PKCS7等自动填充模式更方便。
-
-
数据转换 :在字符串与框架要求的
DataBlob(Uint8Array) 之间转换时,对于含中文等非ASCII字符的文本,建议使用TextEncoder/TextDecoder,而不是简单的stringToUint8Array方法,以避免乱码。 -
密钥安全 :用于长期存储的敏感密钥,应使用 KeyStore(密钥管理服务) 进行安全托管,而不是自己保存在文件或代码中。
-
官方资源:
-
官方示例:这个开源示例演示了文件加解密和签名验签的完整流程,非常有参考价值。
-
API文档 :在开发时,务必查阅你所使用的 SDK版本对应的官方API参考文档,确认具体的接口与参数。
-
核心要点总结
简单来说,cryptoFramework 是鸿蒙安全开发的"工具箱"。使用时记住 三个核心 :1) 导入正确的模块;2) 选择适合的算法(推荐AES-GCM);3) 将密钥交给 KeyStore 管理以确保安全。
cryptoFramework之AES-CBC加密
简介
在鸿蒙中使用AES-CBC的核心是:生成密钥 -> 创建随机IV -> 用 'AES128|CBC|PKCS7' 格式创建Cipher -> 初始化和处理数据 。下图清晰地展示了使用 cryptoFramework 进行 AES 加解密的完整流程和关键决策点:


代码示例
TypeScript
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
// 示例:使用固定的密钥和IV进行加解密(实际应用中IV应随机且不重复)
const KEY_DATA = new Uint8Array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]); // 16字节AES-128密钥
const IV_DATA = new Uint8Array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]); // 16字节IV
async function aesCbcExample() {
// ---------- 1. 准备密钥 ----------
let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES128');
let keyBlob: cryptoFramework.DataBlob = { data: KEY_DATA };
let symKey = await symKeyGenerator.convertKey(keyBlob);
// ---------- 2. 准备IV ----------
let ivBlob: cryptoFramework.DataBlob = { data: IV_DATA };
// ---------- 3. 加密 ----------
let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7');
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivBlob);
let plainText: cryptoFramework.DataBlob = { data: new TextEncoder().encode('Hello, HarmonyOS!') };
let encryptedData = await cipher.doFinal(plainText);
console.info('加密结果(Hex):', Array.from(new Uint8Array(encryptedData.data)).map(b => b.toString(16).padStart(2, '0')).join(''));
// ---------- 4. 解密 ----------
let decipher = cryptoFramework.createCipher('AES128|CBC|PKCS7');
await decipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, ivBlob);
let decryptedData = await decipher.doFinal(encryptedData);
let decryptedText = new TextDecoder().decode(decryptedData.data);
console.info('解密结果:', decryptedText);
}
aesCbcExample().catch(error => {
console.error('加解密过程出错:', error);
});
生成密钥说明
根据鸿蒙(HarmonyOS)ArkTS开发文档,convertKeySync是cryptoFramework中同步转换密钥的核心方法,具体使用规范如下:
功能说明
- 同步转换密钥 :将输入的二进制密钥数据(
DataBlob类型)转换为指定算法类型的密钥对象(SymKey或KeyPair)。 - 适用场景 :
- 对称密钥:如
3DES192、HMAC等算法。 - 非对称密钥:如
Ed25519等算法(需注意数据类型转换)。
- 对称密钥:如
在鸿蒙(HarmonyOS)ArkTS开发中,createSymKeyGenerator 是用于创建对称密钥生成器(SymKeyGenerator)的核心方法,支持生成和转换多种对称密钥(如AES、SM4、HMAC等)。以下是详细说明:
- 参数说明 :
algName: string
指定密钥算法和长度的字符串,支持的取值包括:'AES128'、'AES192'、'AES256''SM4_128''3DES192''HMAC'
若传入无效参数(如'RSA'),会立即抛出错误。
使用步骤与示例
1、生成密钥二进制数据
需将原始密钥(如Base64字符串或字节数组)转换为Uint8Array格式,再封装为DataBlob:
import { buffer } from '@kit.ArkTS';
// 示例1:从Base64字符串转换(Ed25519密钥场景)
let base64Key = "your_base64_encoded_key";
let keyBlob: cryptoFramework.DataBlob = {
new Uint8Array(buffer.from(base64Key, 'base64').buffer)
};
// 示例2:直接定义字节数组(3DES192密钥场景)
function genKeyMaterialBlob(): cryptoFramework.DataBlob {
let arr = [0xba, 0x3d, 0xc2, 0x71, ...]; // 24字节密钥
return { new Uint8Array(arr) };
}
2. 创建密钥生成器
需明确指定算法类型
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
// 对称密钥(如HMAC)
let symKeyGenerator = cryptoFramework.createSymKeyGenerator('HMAC|SHA256');
// 非对称密钥(如Ed25519)
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('Ed25519');
3. 同步转换密钥
调用convertKeySync方法:
// 对称密钥转换
let symKey = symKeyGenerator.convertKeySync(keyBlob);
// 非对称密钥转换
let keyPair = asyKeyGenerator.convertKeySync(keyBlob); // keyBlob需包含公私钥数据
4. 获取转换后的密钥数据
let encodedKey = symKey.getEncoded();
console.info('Key binary ' + encodedKey.data);
5.关键注意事项
-
数据类型必须正确
- 输入密钥的二进制数据需为
Uint8Array类型,不可直接使用Base64字符串。 - 错误示例:未转换Base64直接传入 → 导致
ErrorCode 17630001(参数类型错误)。
- 输入密钥的二进制数据需为
-
密钥长度需匹配算法要求
- 如HMAC算法配合SHA224摘要时,密钥长度必须为28字节 (224位),否则报错
convertSymKey key failed!。 - 非对称算法(如Ed25519)需同时提供有效的公私钥数据。
- 如HMAC算法配合SHA224摘要时,密钥长度必须为28字节 (224位),否则报错
-
同步方法限制
convertKeySync是同步接口,不可用于耗时操作(如大密钥转换),否则阻塞主线程。
错误处理场景
| 错误现象 | 原因分析 | 解决方案 |
|---|---|---|
ErrorCode 17630001 |
输入参数类型错误 | 检查keyBlob是否为Uint8Array |
convertSymKey key failed! |
密钥长度/格式不匹配算法 | 校验算法规格文档中的长度要求 |
| 非对称密钥转换失败 | 公私钥数据不完整/损坏 | 确保密钥对数据完整且未篡改 |
总结 :正确使用
convertKeySync的核心是确保输入密钥数据的类型(Uint8Array)和长度严格符合目标算法要求。
注意事项
在实现AES-CBC时,以下几点至关重要:
-
IV必须是随机的 :实际应用中,每次加密都应使用密码学安全的随机数生成器 生成全新的、不可预测的IV。绝对不能固定或重复使用同一个密钥下的相同IV,这会严重削弱安全性。上述代码中使用固定IV仅用于演示。
-
数据对齐与填充 :CBC模式要求明文长度是16字节(128位)的整数倍 。
PKCS7填充模式会自动在明文末尾添加字节以满足长度要求,解密后会自动移除这些填充字节。这是最常用的安全填充方式。 -
密钥管理 :示例中的硬编码密钥仅用于演示。在生产环境中,密钥必须通过安全的密钥管理系统(如鸿蒙的HUKS)生成和存储。
-
错误处理 :务必使用
try...catch包裹加解密操作,以处理可能出现的初始化失败、数据格式错误等异常。