You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS第三方Passkeys管理器注册失败及密钥返回问题咨询

问题

我们正在开发一款iOS平台的第三方Passkeys管理器应用,已在CredentialProviderViewController中实现以下方法:

func prepareCredentialList(
    for serviceIdentifiers: [ASCredentialServiceIdentifier]
)

func provideCredentialWithoutUserInteraction(
    for credentialRequest: ASCredentialRequest
)
func prepareInterfaceToProvideCredential(
    for credentialRequest: ASCredentialRequest
)
func prepareInterface(
    forPasskeyRegistration registrationRequest: ASCredentialRequest
)

在webauthn.io、webauthn.me等网页测试时,我们的应用会显示为创建Passkey的选项之一,且能收到prepareInterface(forPasskeyRegistration:)的调用,并已按照官方文档指导进行处理,但注册仍失败。我们了解到需在此方法中通过加密库生成Passkey,再调用completeRegistrationRequest(using:completionHandler:),但相关文档匮乏导致调试困难。请问生成Passkey后,如何将其返回给系统?

解决方案

生成Passkey后,按以下步骤即可正确返回给系统:

  1. 转换并验证请求类型
    先将传入的registrationRequest强转为ASPublicKeyCredentialRegistrationRequest,确保拿到WebAuthN注册的完整参数:

    guard let registrationRequest = registrationRequest as? ASPublicKeyCredentialRegistrationRequest else {
        registrationRequest.complete(with: .userCanceled)
        return
    }
    
  2. 生成符合标准的密钥对
    使用CryptoKit或第三方加密库生成ES256算法的椭圆曲线密钥对,然后导出COSE格式的公钥(这是WebAuthN强制要求的公钥编码格式,不能直接用原始公钥数据)。

  3. 构造系统认可的凭证对象
    用生成的密钥信息和请求参数,创建ASPublicKeyCredential实例:

    // 假设已完成密钥生成,得到以下核心数据:
    let credentialID = Data.random(count: 32) // 生成唯一的32字节凭证ID
    let cosePublicKey: Data = // 导出的COSE格式公钥数据
    let attestationObject: Data? = nil // 若依赖方不需要证明,可传nil
    
    let credential = ASPublicKeyCredential(
        credentialID: credentialID,
        publicKey: cosePublicKey,
        attestationObject: attestationObject,
        userHandle: registrationRequest.user.userHandle
    )
    

    注意:userHandle必须和请求中registrationRequest.user.userHandle完全一致,否则系统会判定无效。

  4. 调用完成方法返回凭证
    通过completeRegistrationRequest(using:completionHandler:)将凭证提交给系统,并处理回调结果:

    registrationRequest.completeRegistrationRequest(using: credential) { error in
        if let error = error {
            // 处理系统返回的错误,比如凭证格式错误、依赖方验证失败等
            print("注册失败: \(error.localizedDescription)")
        } else {
            // 注册成功,将Passkey存储到你的应用数据库中
            self.storePasskey(credentialID: credentialID, publicKey: cosePublicKey, userHandle: registrationRequest.user.userHandle)
        }
    }
    
  5. 异常场景处理
    如果密钥生成失败或参数构造出错,直接调用complete(with:)告知系统错误:

    registrationRequest.complete(with: .error(.unknown))
    

调试时重点排查:

  • COSE公钥的格式是否正确(需包含算法标识、曲线参数等标准字段)
  • 凭证ID是否为随机唯一的二进制数据(长度建议16-64字节)
  • 所有参数是否严格匹配WebAuthN协议要求

内容的提问来源于stack exchange,提问作者Jaydip Finava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 17:52:40