React Native for OpenHarmony 实战:三方库 react-native-crypto-js 的鸿蒙化适配指南

react-native-crypto-js 是 crypto-js 在 RN 生态里的一个常用入口包:MD5、HMAC-MD5、AES 口令式加解密,做本地数据摘要、接口签名、配置加密时会用到。

它和"需要把 iOS/Android 实现换成鸿蒙实现"的那类库不一样------它是纯 JavaScript,没有原生代码 ,所以在鸿蒙上不需要原生适配。但这个交付版本有一个值得单独讲的点:它确实改过 JS。

上游 npm 包导出了 HmacMD5,可它一调用就抛 TypeError ------ 因为打包时把 HMAC 依赖的内部模块裁掉了。交付版用 CryptoJS 已有原语按 RFC 2104 把这段实现补齐了。

所以本文要讲清四件事:怎么判断一个库"要不要原生适配"、上游那个 bug 长什么样、交付版的补丁怎么验证、以及这个包实际支持哪些算法(不能按 README 猜)。

环境准备 :本文不重复环境搭建步骤。RNOH(React Native for OpenHarmony)开发环境的完整配置见官方开发者指南:

https://atomgit.com/CPF-RN/docs/blob/main/开发者指南/02-搭建准备/环境初始化.md


一、先说结论:不需要原生适配,但需要一处 JS 修复

项 结论
需要原生适配吗 ❌ 不需要(无 harmony/、无原生代码、无依赖、无 harmony.autolinking)
需要 HAR / ohpm / autolinking / 权限吗 ❌ 都不需要
需要 JS 层修复吗 ✅ 需要 ------ 上游 bundle 的 HmacMD5 一调用就抛 TypeError

"不需要原生适配"和"不需要动代码"是两件事。 一个纯 JS 库也可能因为打包裁剪、平台分支、历史 bug 而在运行时不可用------这类问题不解决,接进来照样跑不起来。

二、判定过程:三步判断一个 RN 库要不要鸿蒙原生适配

这个方法在选库阶段就能用,不用先装进来:

第一步:看 package.json 有没有 harmony 字段

bash 复制代码
npm view <包名> harmony --json

有 harmony.autolinking(ohPackageName / etsPackageClassName / cppPackageClassName / cmakeLibraryTargetName 那四个名字)的,一定是带原生实现的包 ,必须走 link-harmony + ohpm + hvigor。

react-native-crypto-js 的情况:

bash 复制代码
$ npm view react-native-crypto-js version main dependencies --json
{ "version": "1.0.0", "main": "CryptoJS.js" }     # 无 harmony、无 dependencies

第二步:看仓库里有没有 harmony/

bash 复制代码
$ git clone https://atomgit.com/oh-react-native/react-native-crypto-js.git
$ ls react-native-crypto-js
CryptoJS.js  package.json  LICENSE
README.OpenHarmony.md  README.OpenHarmony_CN.md
spec.json  RN_react-native-crypto-js+代码检查报告.md  __tests__/

没有 harmony/、没有 src/ ------ 全部实现就是根目录那一个 CryptoJS.js(124 行的压缩 bundle)。

第三步:读代码里有没有原生调用或平台分支

搜三个关键词就够了:

  • NativeModules / TurboModuleRegistry ------ 有的话在调原生
  • Platform.OS ------ 有的话在按平台分叉行为
  • requireNativeComponent ------ 有的话是原生视图

CryptoJS.js 里一个都没有,纯字符串与位运算。

spec.json 也把性质写明了:

json 复制代码
{
  "implementation": "pure JavaScript; no native module or HAR required",
  "upstreamCommit": "f9bf05dbc6f92400f53204776ad968d20d305ac2"
}

一个容易误判的点 :包里有 android/ 或 ios/ 目录,不代表"有原生实现"。很多库把平台工程放进包里但实际不参与 RN 运行。判断要看有没有被 JS 侧真实调用 ------第一步的 harmony.autolinking 是最可靠的信号。

三、上游那个 bug:导出了,却一调就炸

先复现:

js 复制代码
const CryptoJS = require('react-native-crypto-js');   // npm 上游 1.0.0

typeof CryptoJS.HmacMD5;        // "function"  ← 看起来是有的
CryptoJS.HmacMD5('message', 'secret');
// TypeError: Cannot read properties of undefined (reading 'init')

同一个 bundle 的 MD5 完全正常:

js 复制代码
CryptoJS.MD5('abc').toString();
// "900150983cd24fb0d6963f7d28e17f72"

所以问题只出在 HMAC 接线 :上游打包时把 CryptoJS.algo.HMAC 这类内部模块裁掉了,却忘了把依赖它的 HmacMD5 helper 一起裁掉,于是留下一个**"导出了但一用就炸"的 API**。

这类问题为什么值得警惕? 因为它是"检查存在性通不过"的反面------你对 typeof CryptoJS.HmacMD5 === 'function' 的检查会通过,甚至做静态检查、做类型定义都不会报错。只有真的调用一次才会暴露。

四、交付版怎么修的

交付版与 npm 上游做逐字节 diff,差异只有两类:

复制代码
上游 CryptoJS.js  [16744 字节]  SHA256 = C31A3E861F66C1EE23C207B96540B9B5D813DDEFA4E8AF11D7CAE62EAE7A4DB8
交付 CryptoJS.js  [17784 字节]  SHA256 = 95E43C0117E3E6AADDA6CA43ED8F2BD86F7DD14F2E44589624D87D370280CE21

1 file changed, 27 insertions(+), 9 deletions(-)   # 9 行删除是版权注释去行尾空格

新增的就是 18 行 HmacMD5:

js 复制代码
// The upstream bundle omits the internal HMAC module although it exports the
// helper. Implement the documented MD5 HMAC using the bundled primitives.
CryptoJS.HmacMD5 = function (message, secret) {
  var WordArray = CryptoJS.lib.WordArray;
  var Utf8 = CryptoJS.enc.Utf8;
  var key = typeof secret === 'string' ? Utf8.parse(secret) : secret;
  if (key.sigBytes > 64) key = CryptoJS.MD5(key);
  key = key.clone();
  key.clamp();
  var keyWords = key.words.slice(0);
  while (keyWords.length < 16) keyWords.push(0);
  var innerWords = keyWords.map(function (word) { return word ^ 0x36363636; });
  var outerWords = keyWords.map(function (word) { return word ^ 0x5c5c5c5c; });
  var messageWordArray = typeof message === 'string' ? Utf8.parse(message) : message;
  var inner = CryptoJS.MD5(WordArray.create(innerWords, 64).concat(messageWordArray));
  return CryptoJS.MD5(WordArray.create(outerWords, 64).concat(inner));
};

这就是 RFC 2104 定义的 HMAC:

复制代码
HMAC(K, m) = H( (K ⊕ opad) ‖ H( (K ⊕ ipad) ‖ m ) )

对照着看每一行都在做什么:

代码 RFC 2104 里的含义
if (key.sigBytes > 64) key = CryptoJS.MD5(key) 密钥长于分组长度时,先做一次摘要(MD5 的分组长度是 64 字节)
while (keyWords.length < 16) keyWords.push(0) 密钥补零到 64 字节(16 个字)
word ^ 0x36363636 ipad = 0x36 重复
word ^ 0x5c5c5c5c opad = 0x5c 重复
内层 MD5(ipad ‖ m),外层 MD5(opad ‖ 内层) 嵌套结构

它没有另造算法,而是复用 bundle 里已有的 CryptoJS.MD5 和 WordArray ------在一个被裁剪过的 bundle 里,这是最小侵入的修法。

补丁正确性怎么验

补丁是手写的,就必须独立验证。我用 Node 的 crypto.createHmac('md5') 逐例比对:

复制代码
密钥长度:0, 1, 3, 4, 5, 15, 16, 20, 63, 64, 65, 80, 128, 200, 4097 字节
消息:'' / 'a' / 'message' / 'Harmony RN' / '鸿蒙 RN' / 200 字节长消息
结果:90/90 与 Node HMAC-MD5 一致

特意覆盖了两个容易实现错的边界:

  • 密钥长度 64 与 65 ------ 分组长度是 64,64 字节不该 被摘要、65 字节必须被摘要,改错一边就会在 65 字节上露馅;
  • 密钥长度 0 ------ 空密钥按标准补零。

为什么不直接信那个新增的注释? 因为注释说的是"用已有原语实现文档化的 MD5 HMAC"------它是意图 ,不是证据。90 组独立比对才是证据。

五、能力边界:不能按 README 猜测支持

这个包有个很容易踩的预期差。上游 README 里列了 SHA 系列、PBKDF2、DES 等算法,但这个 npm 包并没有导出它们。

逐个探测 19 个名字:

名称 上游 交付
MD5 / HmacMD5 function function
AES / enc / lib / mode / pad / algo object object
SHA1 / SHA256 / SHA512 undefined undefined
HmacSHA1 / HmacSHA256 / HmacSHA512 undefined undefined
PBKDF2 undefined undefined
DES / TripleDES / RC4 / Rabbit undefined undefined

在 bundle 里搜关键词也印证了:SHA256、PBKDF2、DES、TripleDES、HmacSHA 出现次数都是 0 ,而 MD5 出现 9 次、AES 出现 2 次。

所以这个包实际只有三个能力 :MD5、HmacMD5、AES。交付版因此在 README 里明确写了"不能按 README 猜测支持",并声明能力范围就是这三项。

这是很实用的一条经验 :第三方库的 README 描述的是作者的意图或上游完整版的形态 ,而你 npm install 装到的可能是裁剪过的子集 。判断一个算法能不能用,typeof 一下比读 README 可靠。

六、接入宿主:零原生接线

对照带 harmony/ 的库,这个库少了整整一排接线动作:

接线项 带原生实现的库 react-native-crypto-js
npm install + package.json 加依赖 需要 需要(这个躲不掉)
react-native link-harmony 需要 不需要
工程级 harmony/oh-package.json5 加 HAR 需要 不需要
模块级 harmony/entry/oh-package.json5 加 HAR 需要 不需要
harmony/entry/src/main/ets/RNOHPackagesFactory.ets 注册 Package 需要 不需要
ohos.permission.* 权限声明 视库而定 不需要
metro.config.js 的 watchFolders 需要 本次需要一行(原因见下)

实测一:link-harmony 跳过了它

复制代码
$ node_modules\.bin\react-native link-harmony --verbose
...
info updated 4 file(s), linked 5 libraries, skipped 1 libraries

linked 5 libraries 与加入它之前完全一样 ,react-native-crypto-js 不在列表里------因为它没有 harmony.autolinking 声明。

实测二:Metro 的重定向清单里也没有它

复制代码
[INFO] Redirected imports to 5 harmony-specific third-party package(s):
[INFO] • <已接入的带鸿蒙实现的包> → <同名鸿蒙实现>
...

清单里没有 react-native-crypto-js。

注意:这里"不在清单里"才是对的 。Metro 的这个重定向是给"有鸿蒙变体"的包准备的(把某个包名解析到它的鸿蒙实现),纯 JS 库没有鸿蒙变体可重定向,出现在清单里反而说明有问题。

实测三:模块级 oh-package.json5 一个字没动

构建照样成功,ohpm install --all 0.45 秒。

唯一需要的那一行,以及它为什么可以省

js 复制代码
// metro.config.js
watchFolders: [
  ...
  path.resolve(__dirname, '../react-native-crypto-js'),
],

这一行不是鸿蒙适配 ,而是 file: 本地依赖的通病:file: 装进 node_modules 之后是链接 (Windows 上是 Junction),metro 需要一个 watchFolders 条目才认得出它的真实目录。

从 npm registry 装 (装成真目录)就连这一行都不需要------真正的"零接线"。

七、验证方法:已知值向量 + 独立复算

这个库的输出是确定性的 (MD5、HMAC-MD5,以及用显式 key+IV 的 AES),所以验证方式很明确:逐字节对已知值。

设备侧 100 项断言

测试页把期望值放在 cryptoVectors.json 里(由 PC 端 Node/OpenSSL 现场生成),分四组跑:

组 内容 断言数 结果
A MD5(7)+ HmacMD5(45)+ AES-CBC 加密/解密(12×2) 76 ✅ 76/76
B AES 口令模式往返、随机性、Salted__ 头、密文长度 5 ✅ 5/5
C 19 个导出名的 typeof 与交付声明一致 19 ✅ 19/19
合计 100 ✅ 100/100
D 上游 bundle vs 交付版对比 不计入 如实展示

A 组的向量设计上刻意覆盖边界:

  • MD5:空串、单字符、abc、中英文、1000 字节长文本
  • HmacMD5:15 种密钥长度(0 / 1 / 3 / 4 / 5 / 15 / 16 / 20 / 63 / 64 / 65 / 80 / 128 / 200 / 4097 字节)× 3 种消息------把 HMAC 的块长边界(64)夹在中间
  • AES-CBC:128/192/256 位 × 4 种明文(含空串、中文、100 字节多块),加密与解密各断言一次

AES 用显式 key + IV而不是口令,是因为口令模式每次都带随机 salt、密文不可复现;显式 key+IV 才能拿到确定值去和 OpenSSL 比对。

B 组:口令模式与密文格式

复制代码
口令模式往返一致 ✅
两次加密结果不同(随机 salt)✅
密文不等于明文 ✅
密文头 8 字节 = "Salted__"(hex 53616c7465645f5f)✅
密文总长度 = 32 字节(16 字节头 + 16 字节密文块)✅

Salted__ 这个头说明它用的是 OpenSSL 兼容的口令派生格式 (EVP_BytesToKey + salt)。我用库自身的 API 读这个头,不引入额外依赖:

ts 复制代码
const parsed = CryptoJS.enc.Base64.parse(ciphertext);
const head = CryptoJS.enc.Hex.stringify(
  CryptoJS.lib.WordArray.create(parsed.words.slice(0, 2), 8),
);   // → "53616c7465645f5f" = "Salted__"

C 组:导出能力与交付声明一致

把 19 个名字的 typeof 与交付声明逐一对照(含 11 个必须为 undefined 的名字)。断言"不存在"也是有意义的------它把交付的能力边界钉死,将来上游补包或误改都能立刻发现。

D 组:在设备上直接对比上游 bundle 与交付版

这一组是本文最有说服力的一屏。我把 npm 上游那份有 bug 的 CryptoJS.js 也拷进宿主,和设备上跑的交付版并排调用:

复制代码
• 上游 npm bundle 的 HmacMD5 结果:抛错 → TypeError: Cannot read property 'init' of undefined
• 上游 npm bundle 的 MD5('abc') = 900150983cd24fb0d6963f7d28e17f72(可用)
• 交付版 HmacMD5 结果:7e0d0767775312154ba16fd3af9771a2
• 两者是否一致:否(上游不可用,交付版已修复)

这不是"我推断上游坏了",而是在同一台设备、同一个 JS 引擎上跑出来的对照结果。

PC 端独立复算

设备侧说"和期望值一致"还不够------期望值本身也要可信。所以所有期望值都由 PC 端 Node.js(底层 OpenSSL)算出,关键结论在 PC 端再复算一次:

检查 结果
上游 HmacMD5 调用 ❌ 抛 TypeError: Cannot read properties of undefined (reading 'init')
交付版 HmacMD5 vs Node createHmac('md5') ✅ 90/90 一致
AES-128-CBC / AES-256-CBC(显式 key+IV)vs Node createCipheriv ✅ 逐字节相同
MD5('Harmony RN') ✅ b9f12de3a17ac5fb38584533d2ce5c35(与 Node 一致)
复制代码
aes-128-cbc  交付=lAUC21+ObYF3qZp45Wl3NQ3Sqkb8tOKSz8QkU1ffAww=
             Node=lAUC21+ObYF3qZp45Wl3NQ3Sqkb8tOKSz8QkU1ffAww=  ✓ 一致
aes-256-cbc  交付=RndHlDeJRl7ChXlsIKrF+m4SqGQeld1fE8PyuxgvZDs=
             Node=RndHlDeJRl7ChXlsIKrF+m4SqGQeld1fE8PyuxgvZDs=  ✓ 一致

八、真机验证

验证环境:Pura X View 模拟器,HarmonyOS 7.0.0(26.0.0) Beta2,API 26,ohos-x64。

复制代码
[cryptojs-test] A. 已知值向量(MD5 / HmacMD5 / AES-CBC) -> 76/76 全部通过
[cryptojs-test] B. AES 口令模式与格式 -> 5/5 全部通过
[cryptojs-test] C. 导出能力与交付声明一致 -> 19/19 全部通过
[cryptojs-test]   口令模式密文示例:U2FsdGVkX19rwGYlEmTic2OpA/FCf9CK3hZmFzmvKok=
[cryptojs-test] 对比|上游 npm bundle 的 HmacMD5 结果:抛错 → TypeError: Cannot read property 'init' of undefined
[cryptojs-test] 对比|上游 npm bundle 的 MD5('abc') = 900150983cd24fb0d6963f7d28e17f72(可用)
[cryptojs-test] 对比|交付版 HmacMD5 结果:7e0d0767775312154ba16fd3af9771a2
[cryptojs-test] 对比|两者是否一致:否(上游不可用,交付版已修复)

设备侧行为与 PC 端完全一致 ------ 这既说明"纯 JS 库不需要原生适配",也说明上游那个 bug 是打包裁剪问题,与平台无关。

编译代价:assembleHap 7 分 1 秒 ,HAP 从 79.99 MB 涨到 80.09 MB(约 +102 KB,其中包含两份 16.7 KB 的 bundle、27.5 KB 的向量和主 bundle 的增量)。

能力对照

能力 结果
MD5(text) ✅ 7 组已知值一致(空串 / 单字符 / 中英文 / 1000 字节长文本)
HmacMD5(text, key) ✅ 45 组已知值一致(15 种密钥长度 × 3 种消息),PC 端另复算 90 组
AES.encrypt/decrypt(显式 key+IV) ✅ 128/192/256 位 × 4 种明文,密文与 OpenSSL 逐字节相同
AES 口令模式 ✅ 往返一致、随机 salt、OpenSSL 兼容 Salted__ 格式
导出能力 ✅ 19 个名字的 typeof 与交付声明一致
原生接线 ✅ 零接线(未改 oh-package.json5、未触发 autolinking)

九、已知限制

一、只支持三个能力:MD5、HmacMD5、AES(CBC)。 上游 README 里宣称的 SHA 系列、PBKDF2、DES、TripleDES、RC4、Rabbit 在这个包里没有导出 ,typeof 全部是 undefined。不要按 README 规划功能。

二、AES 的口令模式用 OpenSSL 兼容格式。 密钥由口令 + 随机 salt 按 EVP_BytesToKey 派生,密文带 Salted__ 头。密钥管理与协议升级由业务负责------这个库不提供 KDF 参数选择、不提供版本协商。

三、摘要和 HMAC 是"无认证"的原语组合。 MD5 与 HMAC-MD5 本身不构成安全协议;MD5 早已不适合做抗碰撞用途,用于签名场景时应评估是否该换成更强的摘要(但本包不提供 SHA 系列)。

四、口令模式的随机数质量未评估。 实现依赖运行时的随机源;本次只验证了"两次密文不同",样本检查不等于证明随机性。

五、未测大消息吞吐。 纯 JS 实现对短文本没问题,长文本的性能未做基准测试。

六、交付版相对上游只做了两处改动。 版权注释去尾空格 + 新增 HmacMD5 实现;上游那个"导出了但缺依赖"的问题属于上游打包缺陷,本交付是在 JS 层补齐,不是改上游源码。

七、其他 ROM / 真机未验证。 适配方记录的是 OpenHarmony-7.0.0.105;本次在 HarmonyOS 7.0.0(26.0.0) Beta2 模拟器上通过。

十、常见问题

Q:这个库需要鸿蒙化适配吗?

A:不需要原生适配 ------它是纯 JavaScript,没有 harmony/、没有原生代码、没有依赖、没有 harmony.autolinking。但交付版确实改过 JS :补上了上游缺失的 HmacMD5 实现。所以准确说法是"不需要原生适配,但需要一处 JS 修复"。

Q:为什么 typeof CryptoJS.HmacMD5 是 function,调用却抛错?

A:因为上游打包时把 CryptoJS.algo.HMAC 这类内部模块裁掉了,但保留了对它的引用。typeof 检查、静态检查、类型定义都不会报错 ,只有真的调用一次才会暴露 TypeError: Cannot read properties of undefined (reading 'init')。

Q:交付版是怎么修的?会不会改坏了?

A:用 bundle 里已有的 CryptoJS.MD5 和 WordArray,按 RFC 2104 实现 HMAC-MD5(密钥超 64 字节先摘要、补零到 64 字节、ipad/opad 异或、内外双层 MD5)。正确性用 Node 的 createHmac('md5') 逐例验证:90/90 一致,覆盖密钥长度 0~4097 字节。

Q:README 里写了 SHA256、PBKDF2、DES,为什么我用不了?

A:这个 npm 包没有导出它们 (typeof 全是 undefined)。README 描述的是上游完整版的形态,而你装到的是裁剪过的子集。判断某个算法能不能用,typeof 一下比读 README 可靠。

Q:为什么我在 metro.config.js 里加了一行 watchFolders?

A:这一行不是鸿蒙适配 ,是 file: 本地依赖的通病------file: 装进 node_modules 是链接(Junction),metro 需要 watchFolders 才认真实目录。从 npm registry 装成真目录就不需要这一行。

Q:怎么确认这个库"真的没被 autolinking 接管"?

A:两个信号:① link-harmony 输出的 linked N libraries 不应 因为它增加;② Metro 的 Redirected imports to N ... 清单里不应 出现它。注意这两个信号的方向------Redirected imports 是"鸿蒙变体重定向",只有带鸿蒙实现的包才该出现在里面;纯 JS 库出现在里面反而是异常。

Q:AES 的密文为什么每次都不一样?

A:口令模式下每次加密会生成随机 salt (派生密钥和 IV 用),所以同样明文 + 同样口令也会得到不同密文。这是正确行为。密文以 OpenSSL 兼容格式存储:Base64 解码后前 8 字节是 Salted__,跟着 8 字节 salt。要拿确定性密文就传显式 key + IV(本页 A 组就是这么和 OpenSSL 比对的)。

Q:AES 用的是 CBC 还是别的模式?

A:这个 bundle 里只有 CBC(配合 PKCS7 填充)。GCM、CTR 等模式未包含,也未验证。

Q:怎么确认这个交付版本是对的?

A:四层证据:① 与 npm 上游逐字节 diff,只多了注释格式和 18 行 HmacMD5;② 设备侧 100 项已知值断言全部通过 (期望值由 PC 端 Node/OpenSSL 生成);③ PC 端独立复算------HMAC 90/90、AES 密文与 OpenSSL 逐字节相同;④ 把上游那份 bundle 拷进宿主做同机对比,直接看到"上游抛错 / 交付版正确"。

Q:为什么我在模拟器上编译要这么久?

A:宿主已经带有原生缓存的库,增量加一个纯 JS 库约 6~7 分钟 (hvigor 会把整套流水线走一遍);全新克隆的宿主首次编译要 30~40 分钟。只改 JS 重新打包也是 6~7 分钟,所以别把 UI 微调留到最后做。

小结

这个案子有两层值得记:

第一层是"要不要适配"的判断。 三步就够了:看 package.json 有没有 harmony.autolinking、看仓库有没有 harmony/、看代码有没有原生调用。三步都无,就是纯 JS 库,能省掉整套原生接线和一个 30~40 分钟的首次编译 。这个库的实际接入成本只有一行依赖(+102 KB HAP、7 分钟编译),而且从 npm 装的话连 metro.config.js 都不用改。

第二层是"不需要原生适配"≠"不需要动代码"。 上游 bundle 导出了 HmacMD5,依赖的内部 HMAC 模块却被裁掉了------typeof 是 function,一调用就 TypeError。这类问题最有欺骗性:存在性检查通不过,只有真的调用一次才会暴露。

由此还有两条方法论:

  • 补丁必须独立验证,不能只看注释。 那 18 行是新写的手写实现,它的注释说明的是意图 ,不是证据 。要证明它符合 RFC 2104,就得拿 createHmac('md5') 逐例比对------而且要特意把分组长度边界(64 / 65 字节)和空密钥夹在里面,改错一边立刻露馅。
  • 能力边界要实测,不能读 README。 上游 README 里列了 SHA、PBKDF2、DES,但这个包一个都没导出。第三方库的 README 描述的是作者的意图或上游完整版的形态,你装到的可能是裁剪过的子集。

最后是验证设计上的一点:把"上游 bundle"也拷进宿主、在同一台设备上并排调用,比任何"我推断上游有问题"的说明都直接。做适配时多花十分钟造一个这样的对照,比写三段解释有用。


本篇用到的库

项 内容
三方库 react-native-crypto-js(上游 1.0.0,纯 JavaScript 实现)
交付仓库 https://atomgit.com/oh-react-native/react-native-crypto-js
交付 TAG 1.0.0-ohos-1.0.0
是否需要 HAR / ohpm / autolinking / 权限 都不需要
上游仓库 https://github.com/imchintan/react-native-crypto-js
基线 commit f9bf05dbc6f92400f53204776ad968d20d305ac2
实际导出的能力 MD5、HmacMD5、AES(CBC)
宿主工程 RNOH084Demo(测试页 rnAppKey = CryptoJsTestApp)
json 复制代码
"react-native-crypto-js": "git+https://atomgit.com/oh-react-native/react-native-crypto-js.git#1.0.0-ohos-1.0.0"
ts 复制代码
import CryptoJS from 'react-native-crypto-js';

const digest = CryptoJS.MD5('Harmony RN').toString();          // b9f12de3a17ac5fb38584533d2ce5c35
const mac = CryptoJS.HmacMD5('message', 'secret').toString();  // 7e0d0767775312154ba16fd3af9771a2

// 口令模式:每次随机 salt,密文带 OpenSSL 兼容的 Salted__ 头
const encrypted = CryptoJS.AES.encrypt('hello 鸿蒙', 'secret key 123').toString();
const text = CryptoJS.AES.decrypt(encrypted, 'secret key 123').toString(CryptoJS.enc.Utf8);

// 显式 key + IV:确定性输出,可与 OpenSSL 互操作
const ciphertext = CryptoJS.AES.encrypt(
  CryptoJS.enc.Utf8.parse('HarmonyOS 鸿蒙'),
  CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f'),
  {iv: CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f')},
).toString();
bash 复制代码
# 换页启动测试页(force-stop 不能省,换页参数只在冷启动生效)
hdc shell aa force-stop com.rnoh084.demo
hdc shell aa start -b com.rnoh084.demo -a EntryAbility --ps rnAppKey CryptoJsTestApp

验证环境

项 版本
React Native 0.84.1
React 19.2.3
RNOH(npm / ohpm) @react-native-oh/react-native-harmony / @rnoh/react-native-openharmony 0.84.3
Node.js v24.14.0
DevEco Studio 26.0.0.621
HarmonyOS SDK API 26(26.0.0.32)
设备 HarmonyOS 7.0.0(26.0.0) Beta2 模拟器 Pura X View(ohos-x64)
宿主 HAP 产物 entry-default-signed.hap(80.09 MB)
本次增量构建 assembleHap 7 分 1 秒
验证规模 设备侧 100 项断言全通过;PC 端 HMAC 复算 90/90、AES 与 OpenSSL 逐字节一致

欢迎加入 CPF-RN 鸿蒙社区:https://atomgit.com/CPF-RN

React Native for OpenHarmony 组织:https://atomgit.com/oh-react-native

RN 三方库鸿蒙适配清单:https://atomgit.com/oh-react-native/rn-ohos-adaptation-overview

相关推荐
学以智用1 小时前
jsencrypt.js 完整详解
javascript
贾伟康2 小时前
HarmonyOS API 26 HMAF Skill 可解释任务计划与失败回退
harmonyos·arkts·智能体·skill·hmaf
贾伟康2 小时前
HarmonyOS API 26 HMAF 2.0 意图解析的可解释动作图
harmonyos·arkts·智能体·a2a·hmaf
Hilaku3 小时前
你们公司有 35 岁以上的前端吗?
前端·javascript·程序员
疯华整猫3 小时前
把二十七个 init 从首帧前面搬走:用 Trae 把启动优化钉进 CI
android·性能优化·ai编程
KevinChaos4 小时前
阳台小花园开发手记 03|HarmonyOS 7.0 互动卡片:叶片伸出边框仍与花盆对齐
华为·harmonyos
鸿蒙开发4 小时前
小程序存档写到一半怎么办?双槽保存与损坏恢复实战
前端·javascript·react.js
知忆_IS5 小时前
TerriaMap 开发实战04:MVT数据自定义符号化 - terriajs源码修改
javascript·webgis·terriamap·terriajs
熬夜磕代码丶5 小时前
RN鸿蒙空间音频实战
华为·音视频·harmonyos
行者-全栈开发5 小时前
【鸿蒙心迹】通知与推送集成——emitter 本地通知与推送服务全链路(HarmonyOS 7.x)
华为·harmonyos