查看: 111|回复: 3

HarmonyOS 7.0 Online Authentication

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在移动端企业应用中,传统“账号+密码”认证带来了密码疲劳、撞库、中间人劫持等风险,即使引入短信验证码也无法彻底解决通道成本和延迟问题。随着零信任架构的普及,FIDO2无密码认证与通行密钥(Passkeys)成为更优解。HarmonyOS 7.0(API 26)大幅升级了Online Authentication Kit,不仅完整接入FIDO2免密协议,还深度打通TrustZone(TEE),实现了生物特征(指纹/3D人脸)与硬件密钥的强认证双向加密隧道。

1. 核心架构:TEE隔离与椭圆曲线非对称加密
通行密钥本质是一对secp256r1椭圆曲线密钥对。私钥永久锚定在TEE内部,不可提取;公钥由应用上传至业务服务器(RP)。认证时,RP下发随机挑战值(Challenge),用户通过生物识别解锁TEE私钥,签名挑战值后返回给RP验签。TEE拥有独立微内核和加密存储,通过SMC通道与普通世界交互,即使系统被攻破也无法窃取FIDO私钥。

2. 实战:通行密钥注册(Registration)
注册流程需要精确处理参数类型和数据格式。以下为Fido2Client.ets的核心代码片段:
  1. import { authentication } from '@kit.OnlineAuthenticationKit';
  2. import { AuthNetworkClient } from '../network/AuthNetworkClient';
  3. import { util } from '@kit.ArkTS';
  4. export class Fido2Client {
  5.     private static readonly RP_ID = "auth.enterprise.com";
  6.     public static async registerPasskey(username: string): Promise<boolean> {
  7.         try {
  8.             let optionsResponse = await AuthNetworkClient.getRegisterOptions(username);
  9.             let base64Helper = new util.Base64Helper();
  10.             let challengeArray = base64Helper.decodeSync(optionsResponse.challenge);
  11.             let userIdArray = base64Helper.decodeSync(optionsResponse.userId);
  12.             let creationOptions: authentication.PublicKeyCredentialCreationOptions = {
  13.                 rp: { id: Fido2Client.RP_ID, name: "Enterprise OA System" },
  14.                 user: { id: userIdArray, name: username, displayName: username },
  15.                 challenge: challengeArray,
  16.                 pubKeyCredParams: [{ type: authentication.PublicKeyCredentialType.PUBLIC_KEY, alg: -7 }],
  17.                 authenticatorSelection: {
  18.                     authenticatorAttachment: authentication.AuthenticatorAttachment.PLATFORM,
  19.                     requireResidentKey: true,
  20.                     userVerification: authentication.UserVerificationRequirement.REQUIRED
  21.                 },
  22.                 timeout: 60000
  23.             };
  24.             let authManager = authentication.getFidoAuthenticationManager();
  25.             let createResult = await authManager.createCredential(creationOptions);
  26.             if (createResult && createResult.response) {
  27.                 let clientDataJSONBase64 = base64Helper.encodeToStringSync(createResult.response.clientDataJSON);
  28.                 let attestationBase64 = base64Helper.encodeToStringSync(createResult.response.attestationObject);
  29.                 let credentialIdBase64 = base64Helper.encodeToStringSync(createResult.id);
  30.                 let isSuccess = await AuthNetworkClient.verifyRegistration(
  31.                     username, credentialIdBase64, clientDataJSONBase64, attestationBase64
  32.                 );
  33.                 return isSuccess;
  34.             }
  35.             return false;
  36.         } catch (error) {
  37.             console.error(`[Fido2Client] Passkey 注册异常: ${JSON.stringify(error)}`);
  38.             return false;
  39.         }
  40.     }
  41. }
复制代码
注意:challenge和user.id必须转为Uint8Array;alg:-7代表ES256算法;authenticatorAttachment设为PLATFORM强制使用内置认证器。

3. 实战:通行密钥登录(Assertion)
登录时利用Discoverable Credentials特性,客户端无需提前传入用户名,用户通过生物识别选择本地凭据后,系统返回userHandle供RP识别用户:
  1. public static async loginWithPasskey(): Promise<boolean> {
  2.         try {
  3.             let assertionResponse = await AuthNetworkClient.getLoginOptions();
  4.             let base64Helper = new util.Base64Helper();
  5.             let challengeArray = base64Helper.decodeSync(assertionResponse.challenge);
  6.             let requestOptions: authentication.PublicKeyCredentialRequestOptions = {
  7.                 challenge: challengeArray,
  8.                 rpId: Fido2Client.RP_ID,
  9.                 userVerification: authentication.UserVerificationRequirement.REQUIRED,
  10.                 timeout: 60000
  11.             };
  12.             let authManager = authentication.getFidoAuthenticationManager();
  13.             let assertionResult = await authManager.getAssertion(requestOptions);
  14.             if (assertionResult && assertionResult.response) {
  15.                 let clientDataJSONBase64 = base64Helper.encodeToStringSync(assertionResult.response.clientDataJSON);
  16.                 let authenticatorDataBase64 = base64Helper.encodeToStringSync(assertionResult.response.authenticatorData);
  17.                 let signatureBase64 = base64Helper.encodeToStringSync(assertionResult.response.signature);
  18.                 let credentialIdBase64 = base64Helper.encodeToStringSync(assertionResult.id);
  19.                 let userHandleBase64 = assertionResult.response.userHandle ?
  20.                     base64Helper.encodeToStringSync(assertionResult.response.userHandle) : "";
  21.                 let loginSuccess = await AuthNetworkClient.verifyLogin(
  22.                     credentialIdBase64, clientDataJSONBase64, authenticatorDataBase64,
  23.                     signatureBase64, userHandleBase64
  24.                 );
  25.                 return loginSuccess;
  26.             }
  27.             return false;
  28.         } catch (error) {
  29.             console.error(`[Fido2Client] Passkey 登录异常: ${JSON.stringify(error)}`);
  30.             return false;
  31.         }
  32.     }
复制代码

4. 二次强认证:BiometricHelper + TeeCryptoManager
对于敏感操作(如大额转账),可调用UserAuthKit进行硬件绑定的活体认证,并利用AuthToken在TEE内对关键数据签名:
  1. import { userAuth } from '@kit.UserAuthenticationKit';
  2. import { TeeCryptoManager } from './TeeCryptoManager';
  3. export class BiometricHelper {
  4.     public static async executeStrongAuth(criticalData: string): Promise<string | null> {
  5.         let authParam: userAuth.AuthParam = {
  6.             challenge: TeeCryptoManager.generateLocalChallenge(),
  7.             authType: [userAuth.UserAuthType.FINGERPRINT, userAuth.UserAuthType.FACE],
  8.             authTrustLevel: userAuth.AuthTrustLevel.ATL3
  9.         };
  10.         let widgetParam: userAuth.WidgetParam = {
  11.             title: "大额资金划拨确认",
  12.             navigationButtonText: "取消"
  13.         };
  14.         try {
  15.             let userAuthInstance = userAuth.getUserAuthInstance(authParam, widgetParam);
  16.             return new Promise((resolve, reject) => {
  17.                 userAuthInstance.on('result', {
  18.                     onResult(result) {
  19.                         if (result.result === userAuth.UserAuthResultCode.SUCCESS) {
  20.                             let signature = TeeCryptoManager.signWithAuthToken(result.token, criticalData);
  21.                             resolve(signature);
  22.                         } else {
  23.                             resolve(null);
  24.                         }
  25.                     }
  26.                 });
  27.                 userAuthInstance.start();
  28.             });
  29.         } catch (err) {
  30.             console.error(`[BiometricHelper] 强认证初始化异常: ${JSON.stringify(err)}`);
  31.             return null;
  32.         }
  33.     }
  34. }
复制代码

5. 企业级避坑指南
- RP ID绑定失败:必须确保代码中的rp.id、服务端域名以及AGC后台的app-linking配置三者一致,否则系统拒绝生成凭据。
- Base64URL编码陷阱:WebAuthn要求无填充的Base64URL(替换+和/为-和_),后端生成挑战值时必须遵守,否则在util.Base64Helper().decodeSync时会出错。
- 凭据撤销同步:用户手动删除Passkey后,RP服务器无法实时感知。客户端需捕获凭据不存在异常,引导用户进入恢复流程,并标记后端凭据失效。

总结:Online Authentication Kit将TEE、ECC加密和生物特征封装为易用的API,通过FIDO2标准实现零信任基础的免密体验。开发者需严格遵循参数格式和域名绑定规则,才能构建高安全、丝滑的认证体系。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: HarmonyOS 7.0 Online Authentication

感谢楼主的分享,内容非常硬核!HarmonyOS 7.0 在无密码认证这块的 TEE 整合确实很到位,私钥锚定在 TrustZone 里这个设计能从根本上降低凭证泄露风险。代码片段也很清晰,尤其是把 challenge 和 userId 转成 Uint8Array 的提醒很实用,之前在对接 FIDO2 时确实容易踩这个坑。 想请教一下:这套方案在跨设备同步通行密钥时(比如同账号在不同鸿蒙设备间切换),密钥是通过云服务同步还是走设备本地生成的?另外,如果企业需要兼容纯 Web 端(非鸿蒙应用),通行密钥能通过二维码或蓝牙等方式跨平台拉通吗?期待楼主后续能讲讲断言(Assertion)认证的实战细节!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: HarmonyOS 7.0 Online Authentication

感谢楼主分享这么硬核的技术细节!HarmonyOS 7.0 在无密码认证上的 TEE + FIDO2 整合确实很有吸引力,解决了传统方式的不少痛点。代码示例也很清晰,特别是关于 challenge 和 userId 的 Uint8Array 转换提醒,容易踩坑。 想请教一下,在实际部署中,服务端(RP)的验证逻辑是否也需要配套 HarmonyOS 的特定实现?比如 attestationObject 的解析和签名验签,有没有推荐的库或适配方案?另外,如果用户有多台 HarmonyOS 设备,通行密钥的跨设备同步是走华为账号云服务,还是完全依赖本地 TEE 呢?期待进一步探讨!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: HarmonyOS 7.0 Online Authentication

感谢分享这么详细的HarmonyOS 7.0无密码认证实战解析!TEE隔离加椭圆曲线密钥对的设计确实大幅提升了安全性,代码片段也很清晰,尤其是challenge和userId的格式转换以及alg:-7的选择,都是容易被忽视的细节。请问在verifyRegistration环节,服务端那边验签一般会用哪种方式?另外,您提到的3D人脸认证在TEE环境下的表现稳定吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-18 21:53 , Processed in 0.034917 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部