React Native for OpenHarmony 三方库集成实战:用 UUID、Base64、摘要与 AES 生成离线安全凭证
受测宿主:RN能力库,集成场景所在提交99eea1d9c2d2f7897d75fa439702980cf770523f,TAG0.2.0(场景代码基线)
受测证据:evidence/rn-capability-hub-20260926-scenarios-v033/(保存在本活动工作区)
一、集成目标与边界
本文将离线业务凭证拆分为唯一标识、载荷编码、兼容指纹、安全摘要和对称加密五个环节,并验证它们在同一个 React Native for OpenHarmony 宿主中的集成链路。
Base64 仅负责编码;MD5 和 SHA-256 负责摘要;AES 负责对称加密。示例中的固定口令和 MD5 关联方式仅用于集成验证,不能作为生产密钥方案。
图 1:RN能力库“安全凭证”场景。页面展示五个库的职责和三步集成流程,点击后会生成一次性凭证摘要。
二、五个库怎么分工
| 三方库 | 锁定版本 | 在本场景中的职责 | 连接 |
|---|---|---|---|
react-native-uuid | 2.0.4 | 生成凭证 ID | AtomGit |
react-native-base64 | 0.2.2 | 将 ID 和时间组成字符串载荷并编码 | AtomGit |
react-native-quick-md5 | 3.0.9 | 快速生成兼容旧系统的 MD5 指纹 | AtomGit |
react-native-aes-crypto | 3.3.0 | 对同一载荷生成 SHA-256 | AtomGit |
react-native-crypto-js | 1.0.0 | 使用口令式 AES 生成演示密文 | AtomGit |
五个库都是oh-react-native组织下已发布的 RN for OpenHarmony 交付包,版本和许可证信息以当时交付为准,本文清单截止2026-09-26。对应的适配 TAG 分别是2.0.4-ohos-1.0.0、0.2.2-ohos-1.0.0、3.0.9-ohos-1.0.0、3.3.0-ohos-1.0.0和1.0.0-ohos-1.0.0,均使用单一main交付。五个库均保留 MIT 许可证,请在自己的应用中保留相应声明。
三、环境与依赖锁定
| 组件 | 受测版本 |
|---|---|
| React Native | 0.84.1 |
| React | 19.2.3 |
| RNOH | 0.84.3 |
| DevEco Studio / HarmonyOS SDK | 26.0.0 Release/26.0.0 |
| 测试设备 | 华为畅享 90 Pro Max,OpenHarmony7.0.0.105 |
依赖通过适配仓库 TAG 锁定:
{"dependencies":{"react-native-uuid":"git+https://atomgit.com/oh-react-native/react-native-uuid.git#2.0.4-ohos-1.0.0","react-native-base64":"git+https://atomgit.com/oh-react-native/react-native-base64.git#0.2.2-ohos-1.0.0","react-native-quick-md5":"git+https://atomgit.com/oh-react-native/react-native-quick-md5.git#3.0.9-ohos-1.0.0","react-native-aes-crypto":"git+https://atomgit.com/oh-react-native/react-native-aes-crypto.git#3.3.0-ohos-1.0.0","react-native-crypto-js":"git+https://atomgit.com/oh-react-native/react-native-crypto-js.git#1.0.0-ohos-1.0.0"}}受测宿主实际使用local-packages/中的同版本.tgz,以排除构建期网络变量。两种安装方式都应锁定受测版本,避免使用浮动的latest。
四、在 RNOH 宿主中接入
npminstall./node_modules/.bin/react-native link-harmonycdharmony ohpminstall--allcd..npmrun bundle:harmony /Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw\assembleHap--modemodule-pproduct=default --no-daemonreact-native-uuid、react-native-base64和react-native-crypto-js是纯 JavaScript 实现,不需要 HAR 或新增权限。react-native-quick-md5和react-native-aes-crypto有鸿蒙原生接线,需要将包内 HAR 作为依赖加入宿主,并让link-harmony生成对应的 ArkTS/C++ Package 注册。本场景不额外申请网络权限,也不依赖后台服务。
从调用链看,五个库并不是同一种接入方式:
JS 业务函数 ├─ react-native-uuid / react-native-base64 / react-native-crypto-js → Metro → JS 实现 └─ react-native-quick-md5 / react-native-aes-crypto → TurboModule / JSI → HAR → OpenHarmony 系统能力五、核心集成代码
以下是 RN能力库“生成安全凭证”的核心实现:
import Aes from 'react-native-aes-crypto'; import base64 from 'react-native-base64'; import CryptoJS from 'react-native-crypto-js'; import {stringMd5} from 'react-native-quick-md5'; import uuid from 'react-native-uuid'; type Credential = { id: string; payload: string; md5: string; sha256: string; cipherText: string; }; async function createCredential(): Promise<Credential> { const id = String(uuid.v4()); const payload = base64.encode(`${id}|${Date.now()}`); const md5 = stringMd5(payload); const sha256 = await Aes.sha256(payload); const cipherText = CryptoJS.AES.encrypt(payload, md5).toString(); return {id, payload, md5, sha256, cipherText}; }这段代码中只有Aes.sha256()是异步函数,所以必须在async函数里用await。uuid.v4()和stringMd5()按当前交付包是同步返回;base64.encode()返回编码后的字符串;CryptoJS.AES.encrypt()返回可传输的 Base64 形式密文。
业务界面不应把密文直接全量显示在列表里。本 Demo 只展示 ID 前 8 位、两个摘要前 8 位和密文长度,既能让用户看到每一步确实执行,又不把完整凭证留在屏幕上。
图 2:react-native-uuid生成一个新的 RFC 4122 v4 ID。
图 3:react-native-quick-md5对文本载荷返回小写十六进制 MD5。它适合做旧协议兼容或非对抗性校验,不适合密码存储。
图 4:react-native-aes-crypto对同一载荷返回 SHA-256 摘要。
图 5:react-native-base64执行载荷的编码与解码回路。Base64 不提供保密性。
图 6:react-native-crypto-js生成 AES 密文,界面展示密文长度而不展示密文内容。
六、错误处理和组件生命周期
这个流水线有同步和异步两类失败。UUID、Base64 和 MD5 的参数错误会直接在当前调用中抛出;SHA-256 以 Promise 拒绝错误;AES 的口令、载荷或编码不合法时也不应被当作空字符串成功。业务层用一个try/catch统一收口,将失败记入当前操作日志,而不要只展示一个“生成失败”的笼统文案。
async function onCreateCredential() { setBusy(true); try { const credential = await createCredential(); setResult(`凭证 ${credential.id.slice(0, 8)} · MD5 ${credential.md5.slice(0, 8)} · SHA ${credential.sha256.slice(0, 8)} · AES ${credential.cipherText.length} 字符`); } catch (error) { setResult(`凭证生成失败:${String(error)}`); } finally { setBusy(false); } }如果异步调用可能在组件卸载后返回,应增加请求序号或取消标记,防止过期回调写入页面状态。
七、真机验证
本次用受测 HAP 在一台 OpenHarmony7.0.0.105真机上执行这个场景。验证前已设置设备唤醒并覆盖灭屏超时,但这只是方便连续操作,不代表应用业务会永久阻止灭屏。
| 场景 | 操作 | 实测结果 | 结论 |
|---|---|---|---|
| 生成唯一 ID | 点击“生成安全凭证” | 返回凭证 ID 前 8 位 | 通过 |
| 编码与指纹 | 对同一载荷调用 Base64、MD5和 SHA-256 | 页面显示 MD5 前 8 位、SHA 前 8 位 | 通过 |
| AES 密文 | 以 MD5 字符串作演示口令调用 AES | 密文长度显示为128字符 | 通过 |
| 连续场景回归 | 运行安全凭证后继续运行其他 5 个集成场景 | 六个场景全部通过,未发现 RN JS 未处理异常或崩溃 | 通过 |
0.3.1 受测 HAP SHA-256 为a0f079982142ef5eb836f439af5e71c8f31f33c4988e80ab2a7575bee64b1f03。对应场景截图02-secure-credential.png的 SHA-256 为4ee1bf9f0dd4edc3c5732dabeb20ac431b04dea33ffbc8cb105b318f0505d064,可以用来确认文章图片没有被其他版本替换。
八、安全与验证边界
- 它不是生产密钥管理。示例用 MD5 作为 CryptoJS 口令,只是为了把多个库的调用关系连起来。生产应使用随机密钥、安全存储、密钥轮换和服务端验证。
- 它不是防重放协议。
Date.now()只是让载荷看起来不同,不能代替服务端 nonce、过期时间和已使用 ID 记录。 - MD5 不提供安全完整性。如果业务要防止被篡改,应考虑 HMAC、数字签名或带认证的 AEAD 方案。
react-native-aes-crypto的 CBC/CTR 接口本身也不附带消息认证,不要只加密不验证。 - 平台覆盖有边界。本文只验证了 RN
0.84.1+ RNOH0.84.3+ OpenHarmony7.0.0.105和一台真机,没有据此声称所有 ROM、平板和其他系统版本都兼容。
九、参考链接
- RN能力库宿主
- react-native-uuid
- react-native-base64
- react-native-quick-md5
- react-native-aes-crypto
- react-native-crypto-js
- RN for OpenHarmony 社区