-
-
[原创]FIDO再升级!实现无密码秒级登录、支付
-
发表于: 6小时前 129
-
当前数字时代,人们日常频繁使用的密码,成了"记忆负担",密码太短不安全,密码太长又记不住,如果忘记密码,找回流程也较繁琐,严重影响了用户在应用登录或支付场景中的使用体验。
基于此,HarmonyOS SDK在线认证服务(Online Authentication Kit)遵循FIDO(Fast Identity Online)、FIDO2、IIFAA(互联网可信认证联盟)和SOTER标准免密认证规范,提供了免密身份认证的移动端能力,并基于FIDO2标准协议构建了产品化的通行密钥能力,借用通行密钥,用户可使用指纹、人脸或手机解锁PIN码登录应用,实现一种简单又安全的登录方式。
场景介绍
通行密钥服务主要提供了通行密钥注册、本地免密认证和跨设备扫码认证的能力,具体应用场景如下:
● 注册通行密钥
在需要给本地应用或网页提供一种方便、快速、安全的登录方式时,应用可以使用通行密钥服务的通行密钥注册能力为用户创建通行密钥。

● 使用通行密钥登录本设备的应用或网页账号
用户在登录本设备的应用或者网页账号时,需要验证用户的身份,可以使用通行密钥服务的本地免密认证能力,实现快速登录。

● 使用通行密钥跨设备扫码登录其他设备的应用或网页账号
用户在其他设备上登录应用或网页时,需要验证用户的身份,可以使用通行密钥服务的跨设备扫码认证能力。

约束与限制
应用需满足以下条件,才能使用该功能。
开发者的业务需要接入符合FIDO2标准的协议,并部署符合FIDO2标准协议的FIDO服务端。
移动端设备需要支持生物特征(指纹或3D人脸),且当前移动端设备支持ATL4级别的认证可信等级。
通行密钥服务需要联网以及蓝牙能力,以便提供完整的在线身份校验服务。应用在调用本服务API前,需将通行密钥服务联网、使用蓝牙行为向用户明示,并且取得用户同意。
通行密钥服务需要将三方应用中的用户昵称及标识符信息上传至网络中继服务器,用于跨设备扫码认证场景,以便实现两台设备的认证数据通信。应用在调用本服务API前,需将收集的个人数据信息向用户明示,并且取得用户同意。
开发步骤
通行密钥服务提供基于FIDO2标准协议的FIDO客户端实现,这里仅演示FIDO客户端相关API的使用,涉及应用服务器及FIDO服务器的相关处理由开发者自行实现,请参考FIDO2标准协议。
需要业务方自行根据FIDO2标准协议部署FIDO服务器。
导入相关模块。
import { BusinessError } from '@kit.BasicServicesKit';
import { UIContext } from '@kit.ArkUI'
import { common } from '@kit.AbilityKit';
import { fido2 } from '@kit.OnlineAuthenticationKit';注册通行密钥。
在注册通行密钥阶段,先要获取能力信息。调用getClientCapabilities接口获取认证能力列表,并且调用getPlatformAuthenticators接口获取平台认证器能力信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | uiContext1: UIContext = this.getUIContext();uiContext: common.UIAbilityContext = this.uiContext1.getHostContext() as common.UIAbilityContext; // 使用uiContext需要获取页面UIAbility的Context,一个页面获取一次即可try { // 获取认证能力列表 let clientCapabilities: Map<fido2.ClientCapability, boolean> = await fido2.getClientCapabilities(this.uiContext); console.info("Succeeded in doing getClientCapabilities.");} catch (error) { let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(`Failed to call getClientCapabilities error code is ${code}, message is ${message}`); // 业务根据错误码判断异常类型,进行相应处理,详见错误码参考}try { // 获取平台认证器能力 let platformAuthenticators: Array<fido2.AuthenticatorMetadata> = await fido2.getPlatformAuthenticators(this.uiContext); console.info("Succeeded in doing getPlatformAuthenticators.");} catch (error) { let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(`Failed to call getPlatformAuthenticators error code is ${code}, message is ${message}`); // 业务根据错误码判断异常类型,进行相应处理,详见错误码参考} |
接着,访问FIDO服务器,获取注册报文,就可以调用register接口进行通行密钥注册了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // pkOptions为应用从FIDO服务端获取的注册报文, credentialCreationOp为应用组装注册信息let credentialCreationOp: fido2.CredentialCreationOptions = { publicKey: pkOptions};try { // 调用register进行通行密钥注册 let publicKeyAttestationCredential: fido2.PublicKeyAttestationCredential = await fido2.register(this.uiContext, credentialCreationOp);} catch (error) { let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(`Failed to call register error code is ${code}, message is ${message}`); // 业务根据错误码判断异常类型,进行相应处理,详见错误码参考} |
最后,应用使用注册结果(publicKeyAttestationCredential)组装注册响应报文,发送至FIDO服务端进行验证,获取注册结果报文。
- 使用通行密钥进行身份认证。
在使用通行密钥进行身份认证阶段,先要获取能力信息,调用getClientCapabilities接口获取认证能力列表,并且调用getPlatformAuthenticators接口获取平台认证器能力信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // 使用uiContext需要获取页面UIAbility的Context,一个页面获取一次即可let uiContext: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;try { // 获取认证能力列表 let clientCapabilities: Map<fido2.ClientCapability, boolean> = await fido2.getClientCapabilities(this.uiContext); console.info("Succeeded in doing getClientCapabilities.");} catch (error) { let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(`Failed to call getClientCapabilities error code is ${code}, message is ${message}`); // 业务根据错误码判断异常类型,进行相应处理,详见错误码参考}try { // 获取平台认证器能力 let platformAuthenticators: Array<fido2.AuthenticatorMetadata> = await fido2.getPlatformAuthenticators(this.uiContext); console.info("Succeeded in doing getPlatformAuthenticators.");} catch (error) { let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(`Failed to call getPlatformAuthenticators error code is ${code}, message is ${message}`); // 业务根据错误码判断异常类型,进行相应处理,详见错误码参考} |
接着,通过访问FIDO服务器,获取认证报文,并调用authenticate接口进行认证。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // authPub为应用从FIDO服务端获取的认证报文,authCredentialRequestOptions为应用组装的认证信息let authCredentialRequestOptions: fido2.CredentialRequestOptions = { publicKey: authPub, mediation: "optional" as fido2.CredentialMediationRequirement}try { // 调用authenticate接口进行认证 let pkAssertionCredential: fido2.PublicKeyAssertionCredential = await fido2.authenticate(this.uiContext, authCredentialRequestOptions);} catch (error) { let message = (error as BusinessError).message; let code = (error as BusinessError).code; console.error(`Failed to call authenticateerror code is ${code}, message is ${message}`); // 业务根据错误码判断异常类型,进行相应处理,详见错误码参考} |
最后,应用使用认证结果(pkAssertionCredential)组装认证响应报文,发送至FIDO服务端进行验证,获取认证结果报文。
了解更多详情>>
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!