HarmonyOS 7.0 Online Authentication
在移动端企业应用中,传统“账号+密码”认证带来了密码疲劳、撞库、中间人劫持等风险,即使引入短信验证码也无法彻底解决通道成本和延迟问题。随着零信任架构的普及,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的核心代码片段:
import { authentication } from '@kit.OnlineAuthenticationKit';
import { AuthNetworkClient } from '../network/AuthNetworkClient';
import { util } from '@kit.ArkTS';
export class Fido2Client {
private static readonly RP_ID = "auth.enterprise.com";
public static async registerPasskey(username: string): Promise<boolean> {
try {
let optionsResponse = await AuthNetworkClient.getRegisterOptions(username);
let base64Helper = new util.Base64Helper();
let challengeArray = base64Helper.decodeSync(optionsResponse.challenge);
let userIdArray = base64Helper.decodeSync(optionsResponse.userId);
let creationOptions: authentication.PublicKeyCredentialCreationOptions = {
rp: { id: Fido2Client.RP_ID, name: "Enterprise OA System" },
user: { id: userIdArray, name: username, displayName: username },
challenge: challengeArray,
pubKeyCredParams: [{ type: authentication.PublicKeyCredentialType.PUBLIC_KEY, alg: -7 }],
authenticatorSelection: {
authenticatorAttachment: authentication.AuthenticatorAttachment.PLATFORM,
requireResidentKey: true,
userVerification: authentication.UserVerificationRequirement.REQUIRED
},
timeout: 60000
};
let authManager = authentication.getFidoAuthenticationManager();
let createResult = await authManager.createCredential(creationOptions);
if (createResult && createResult.response) {
let clientDataJSONBase64 = base64Helper.encodeToStringSync(createResult.response.clientDataJSON);
let attestationBase64 = base64Helper.encodeToStringSync(createResult.response.attestationObject);
let credentialIdBase64 = base64Helper.encodeToStringSync(createResult.id);
let isSuccess = await AuthNetworkClient.verifyRegistration(
username, credentialIdBase64, clientDataJSONBase64, attestationBase64
);
return isSuccess;
}
return false;
} catch (error) {
console.error(` Passkey 注册异常: ${JSON.stringify(error)}`);
return false;
}
}
}
注意:challenge和user.id必须转为Uint8Array;alg:-7代表ES256算法;authenticatorAttachment设为PLATFORM强制使用内置认证器。
3. 实战:通行密钥登录(Assertion)
登录时利用Discoverable Credentials特性,客户端无需提前传入用户名,用户通过生物识别选择本地凭据后,系统返回userHandle供RP识别用户:
public static async loginWithPasskey(): Promise<boolean> {
try {
let assertionResponse = await AuthNetworkClient.getLoginOptions();
let base64Helper = new util.Base64Helper();
let challengeArray = base64Helper.decodeSync(assertionResponse.challenge);
let requestOptions: authentication.PublicKeyCredentialRequestOptions = {
challenge: challengeArray,
rpId: Fido2Client.RP_ID,
userVerification: authentication.UserVerificationRequirement.REQUIRED,
timeout: 60000
};
let authManager = authentication.getFidoAuthenticationManager();
let assertionResult = await authManager.getAssertion(requestOptions);
if (assertionResult && assertionResult.response) {
let clientDataJSONBase64 = base64Helper.encodeToStringSync(assertionResult.response.clientDataJSON);
let authenticatorDataBase64 = base64Helper.encodeToStringSync(assertionResult.response.authenticatorData);
let signatureBase64 = base64Helper.encodeToStringSync(assertionResult.response.signature);
let credentialIdBase64 = base64Helper.encodeToStringSync(assertionResult.id);
let userHandleBase64 = assertionResult.response.userHandle ?
base64Helper.encodeToStringSync(assertionResult.response.userHandle) : "";
let loginSuccess = await AuthNetworkClient.verifyLogin(
credentialIdBase64, clientDataJSONBase64, authenticatorDataBase64,
signatureBase64, userHandleBase64
);
return loginSuccess;
}
return false;
} catch (error) {
console.error(` Passkey 登录异常: ${JSON.stringify(error)}`);
return false;
}
}
4. 二次强认证:BiometricHelper + TeeCryptoManager
对于敏感操作(如大额转账),可调用UserAuthKit进行硬件绑定的活体认证,并利用AuthToken在TEE内对关键数据签名:
import { userAuth } from '@kit.UserAuthenticationKit';
import { TeeCryptoManager } from './TeeCryptoManager';
export class BiometricHelper {
public static async executeStrongAuth(criticalData: string): Promise<string | null> {
let authParam: userAuth.AuthParam = {
challenge: TeeCryptoManager.generateLocalChallenge(),
authType: ,
authTrustLevel: userAuth.AuthTrustLevel.ATL3
};
let widgetParam: userAuth.WidgetParam = {
title: "大额资金划拨确认",
navigationButtonText: "取消"
};
try {
let userAuthInstance = userAuth.getUserAuthInstance(authParam, widgetParam);
return new Promise((resolve, reject) => {
userAuthInstance.on('result', {
onResult(result) {
if (result.result === userAuth.UserAuthResultCode.SUCCESS) {
let signature = TeeCryptoManager.signWithAuthToken(result.token, criticalData);
resolve(signature);
} else {
resolve(null);
}
}
});
userAuthInstance.start();
});
} catch (err) {
console.error(` 强认证初始化异常: ${JSON.stringify(err)}`);
return null;
}
}
}
5. 企业级避坑指南
- RP ID绑定失败:必须确保代码中的rp.id、服务端域名以及AGC后台的app-linking配置三者一致,否则系统拒绝生成凭据。
- Base64URL编码陷阱:WebAuthn要求无填充的Base64URL(替换+和/为-和_),后端生成挑战值时必须遵守,否则在util.Base64Helper().decodeSync时会出错。
- 凭据撤销同步:用户手动删除Passkey后,RP服务器无法实时感知。客户端需捕获凭据不存在异常,引导用户进入恢复流程,并标记后端凭据失效。
总结:Online Authentication Kit将TEE、ECC加密和生物特征封装为易用的API,通过FIDO2标准实现零信任基础的免密体验。开发者需严格遵循参数格式和域名绑定规则,才能构建高安全、丝滑的认证体系。
Re: HarmonyOS 7.0 Online Authentication
感谢楼主的分享,内容非常硬核!HarmonyOS 7.0 在无密码认证这块的 TEE 整合确实很到位,私钥锚定在 TrustZone 里这个设计能从根本上降低凭证泄露风险。代码片段也很清晰,尤其是把 challenge 和 userId 转成 Uint8Array 的提醒很实用,之前在对接 FIDO2 时确实容易踩这个坑。 想请教一下:这套方案在跨设备同步通行密钥时(比如同账号在不同鸿蒙设备间切换),密钥是通过云服务同步还是走设备本地生成的?另外,如果企业需要兼容纯 Web 端(非鸿蒙应用),通行密钥能通过二维码或蓝牙等方式跨平台拉通吗?期待楼主后续能讲讲断言(Assertion)认证的实战细节!Re: HarmonyOS 7.0 Online Authentication
感谢楼主分享这么硬核的技术细节!HarmonyOS 7.0 在无密码认证上的 TEE + FIDO2 整合确实很有吸引力,解决了传统方式的不少痛点。代码示例也很清晰,特别是关于 challenge 和 userId 的 Uint8Array 转换提醒,容易踩坑。 想请教一下,在实际部署中,服务端(RP)的验证逻辑是否也需要配套 HarmonyOS 的特定实现?比如 attestationObject 的解析和签名验签,有没有推荐的库或适配方案?另外,如果用户有多台 HarmonyOS 设备,通行密钥的跨设备同步是走华为账号云服务,还是完全依赖本地 TEE 呢?期待进一步探讨!Re: HarmonyOS 7.0 Online Authentication
感谢分享这么详细的HarmonyOS 7.0无密码认证实战解析!TEE隔离加椭圆曲线密钥对的设计确实大幅提升了安全性,代码片段也很清晰,尤其是challenge和userId的格式转换以及alg:-7的选择,都是容易被忽视的细节。请问在verifyRegistration环节,服务端那边验签一般会用哪种方式?另外,您提到的3D人脸认证在TEE环境下的表现稳定吗?
页:
[1]