Flutter适配ArkTS 严格模式下集成 crypto-js:arkts-no-ns-as-obj 与对象字面量限制的破解
维度原生 cryptoFrameworkDES 支持❌ 不支持✅ 支持3DES/AES✅ 支持✅ 支持性能高(原生)中(JS)集成难度低(若支持 DES)低跨平台一致性与 Android/iOS 一致结论:在 HarmonyOS 上实现 DES,当前唯一可行且推荐的方式是使用。
Flutter鸿蒙 原生 cryptoFramework 不支持 DES 的替代方案
一、问题现象
在 HarmonyOS 上使用官方 @ohos.security.cryptoFramework 实现 DES 加密时,会遇到以下情况之一:
- 找不到 DES 相关算法常量
- 调用
createCipher('DES|CBC|PKCS7')报错或不支持 - 文档中仅列出 3DES、AES 等算法,无 DES
1.1 典型错误
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
// ❌ DES 不在支持列表中
let cipherAlgName = 'DES|CBC|PKCS7';
let cipher = cryptoFramework.createCipher(cipherAlgName);
// 报错:Algorithm DES is not supported
二、根本原因
2.1 HarmonyOS 安全策略
HarmonyOS 的 cryptoFramework 出于安全合规考虑,仅支持以下对称加密算法(以 API 12 为例):
| 算法 | 支持情况 | 说明 |
|---|---|---|
| AES | ✅ 支持 | 128/192/256 位 |
| 3DES | ✅ 支持 | 即 TDES |
| DES | ❌ 不支持 | 已视为弱算法,从 API 中移除 |
| SM4 | ✅ 支持 | 国密算法 |
DES 密钥仅 56 位有效,易受暴力破解,NIST 等机构已不建议在新系统中使用。因此 HarmonyOS 原生不提供 DES 支持。
2.2 业务兼容性需求
许多存量系统、第三方接口仍使用 DES,Flutter 插件需在 Android/iOS/HarmonyOS 上保持一致的加密结果。因此必须在不依赖原生 DES 的前提下,在 HarmonyOS 上实现等效算法。
三、替代方案:使用 @ohos/crypto-js
3.1 方案选型
| 方案 | 优点 | 缺点 |
|---|---|---|
| 原生 cryptoFramework | 性能好、系统级支持 | 不支持 DES |
| @ohos/crypto-js | 支持 DES、与 Web 版兼容、易集成 | 纯 JS 实现,大数据量略慢 |
| 自实现 DES | 无第三方依赖 | 工作量大、易出错、维护成本高 |
推荐:使用 @ohos/crypto-js,它是 crypto-js 的 OpenHarmony 移植版,支持 DES/CBC/Pkcs7,与 Android 的 DES/CBC/PKCS5Padding 在 8 字节分组下等效。
3.2 依赖配置
在 ohos/oh-package.json5 中添加:
{
"name": "flutter_des",
"version": "1.0.0",
"description": "DES plugin",
"dependencies": {
"@ohos/crypto-js": "^2.0.4"
}
}
执行 ohpm install 安装依赖。
3.3 算法等效性说明
| 平台 | 算法写法 | 实际效果 |
|---|---|---|
| Android | DES/CBC/PKCS5Padding | 8 字节分组,PKCS5 与 PKCS7 等效 |
| iOS/macOS | kCCAlgorithmDES, kCCOptionPKCS7Padding | 同上 |
| HarmonyOS (crypto-js) | DES/CBC/Pkcs7 | 与 Android 结果一致 |
CryptoJS 默认使用 CBC 模式和 Pkcs7 填充,配置 { iv: ivWA } 即可,无需额外指定 mode 和 padding。
四、完整实现示例
4.1 加密
import { CryptoJS } from '@ohos/crypto-js';
function encrypt(data: string, key: string, iv: string): Uint8Array | null {
try {
let keyWA = CryptoJS.enc.Utf8.parse(key);
let ivWA = CryptoJS.enc.Utf8.parse(iv);
// 默认 CBC + Pkcs7,与 Android PKCS5Padding 等效
let encrypted = CryptoJS.DES.encrypt(data, keyWA, { iv: ivWA });
return wordArrayToBytes(encrypted.ciphertext);
} catch (e) {
return null;
}
}
4.2 解密
function decryptFromHex(hexStr: string, key: string, iv: string): string | null {
try {
let wordArray = CryptoJS.enc.Hex.parse(hexStr);
let base64Str = CryptoJS.enc.Base64.stringify(wordArray);
let keyWA = CryptoJS.enc.Utf8.parse(key);
let ivWA = CryptoJS.enc.Utf8.parse(iv);
let decrypted = CryptoJS.DES.decrypt(base64Str, keyWA, { iv: ivWA });
return decrypted.toString(CryptoJS.enc.Utf8);
} catch (e) {
return "";
}
}
4.3 WordArray 转 Uint8Array
CryptoJS 内部使用 WordArray(32 位字数组),需转换为 Uint8Array 才能与 Flutter 的 Uint8List 对接:
function wordArrayToBytes(wa: CryptoJS.lib.WordArray): Uint8Array {
let words = wa.words;
let sigBytes = wa.sigBytes;
let u8 = new Uint8Array(sigBytes);
let offset = 0;
for (let i = 0; i < words.length && offset < sigBytes; i++) {
let word = words[i];
u8[offset++] = (word >>> 24) & 0xff;
if (offset < sigBytes) u8[offset++] = (word >>> 16) & 0xff;
if (offset < sigBytes) u8[offset++] = (word >>> 8) & 0xff;
if (offset < sigBytes) u8[offset++] = word & 0xff;
}
return u8;
}
五、跨平台结果一致性验证
使用相同明文、密钥、IV 在 Android 与 HarmonyOS 上加密,结果应完全一致:
// Dart 测试
final plain = 'hello';
final key = '12345678';
final iv = '01234567';
// Android 与 HarmonyOS 的 encryptToHex 结果应相同
final hex = await FlutterDes().encryptToHex(plain, key, iv: iv);
// 例如:'XXXXXXXX'(两平台一致)
建议编写单元测试,对比各平台的 hex/base64 输出。
六、性能与安全建议
6.1 性能
- crypto-js 为纯 JavaScript 实现,大数据量(如 >1MB)时性能不如原生
- 可考虑在 Dart 层做分块加密,或对超大 payload 给出提示
6.2 安全
- DES 仅用于兼容存量系统,新业务建议使用 AES-256
- 密钥、IV 需安全存储,避免硬编码
七、方案对比总结
| 维度 | 原生 cryptoFramework | @ohos/crypto-js |
|---|---|---|
| DES 支持 | ❌ 不支持 | ✅ 支持 |
| 3DES/AES | ✅ 支持 | ✅ 支持 |
| 性能 | 高(原生) | 中(JS) |
| 集成难度 | 低(若支持 DES) | 低 |
| 跨平台一致性 | - | 与 Android/iOS 一致 |
结论:在 HarmonyOS 上实现 DES,当前唯一可行且推荐的方式是使用 @ohos/crypto-js。
八、参考资料
更多推荐


所有评论(0)