React Native for OpenHarmony 三方库集成实战:用 UUID、Base64、摘要与 AES 生成离线安全凭证

受测宿主:RN能力库,集成场景所在提交 99eea1d9c2d2f7897d75fa439702980cf770523f,TAG 0.2.0(场景代码基线)

受测证据:evidence/rn-capability-hub-20260926-scenarios-v033/(保存在本活动工作区)

一、集成目标与边界

本文将离线业务凭证拆分为唯一标识、载荷编码、兼容指纹、安全摘要和对称加密五个环节,并验证它们在同一个 React Native for OpenHarmony 宿主中的集成链路。

Base64 仅负责编码;MD5 和 SHA-256 负责摘要;AES 负责对称加密。示例中的固定口令和 MD5 关联方式仅用于集成验证,不能作为生产密钥方案。

RN能力库安全凭证场景

图 1:RN能力库“安全凭证”场景。页面展示五个库的职责和三步集成流程,点击后会生成一次性凭证摘要。

二、五个库怎么分工

三方库锁定版本在本场景中的职责连接
react-native-uuid2.0.4生成凭证 IDAtomGit
react-native-base640.2.2将 ID 和时间组成字符串载荷并编码AtomGit
react-native-quick-md53.0.9快速生成兼容旧系统的 MD5 指纹AtomGit
react-native-aes-crypto3.3.0对同一载荷生成 SHA-256AtomGit
react-native-crypto-js1.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 Native0.84.1
React19.2.3
RNOH0.84.3
DevEco Studio / HarmonyOS SDK26.0.0 Release / 26.0.0
测试设备华为畅享 90 Pro Max,OpenHarmony 7.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 宿主中接入

npm install
./node_modules/.bin/react-native link-harmony
cd harmony
ohpm install --all
cd ..
npm run bundle:harmony
/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw \
  assembleHap --mode module -p product=default --no-daemon

react-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。

MD5 摘要结果

图 3:react-native-quick-md5 对文本载荷返回小写十六进制 MD5。它适合做旧协议兼容或非对抗性校验,不适合密码存储。

SHA-256 摘要结果

图 4:react-native-aes-crypto 对同一载荷返回 SHA-256 摘要。

Base64 编解码往返结果

图 5:react-native-base64 执行载荷的编码与解码回路。Base64 不提供保密性。

AES 加密结果

图 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 在一台 OpenHarmony 7.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,可以用来确认文章图片没有被其他版本替换。

八、安全与验证边界

  1. 它不是生产密钥管理。 示例用 MD5 作为 CryptoJS 口令,只是为了把多个库的调用关系连起来。生产应使用随机密钥、安全存储、密钥轮换和服务端验证。
  2. 它不是防重放协议。 Date.now() 只是让载荷看起来不同,不能代替服务端 nonce、过期时间和已使用 ID 记录。
  3. MD5 不提供安全完整性。 如果业务要防止被篡改,应考虑 HMAC、数字签名或带认证的 AEAD 方案。react-native-aes-crypto 的 CBC/CTR 接口本身也不附带消息认证,不要只加密不验证。
  4. 平台覆盖有边界。 本文只验证了 RN 0.84.1 + RNOH 0.84.3 + OpenHarmony 7.0.0.105 和一台真机,没有据此声称所有 ROM、平板和其他系统版本都兼容。

九、参考链接

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐