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

Xamarin.iOS真机调用DCAppAttestService.AttestKeyAsync报error2

问题根因

两个报错分别来自代码逻辑错误和SDK版本问题:

  • com.apple.devicecheck.error error 2对应Apple官方定义的无效输入错误,原因是传入AttestKeyAsync的客户端哈希格式不符合要求:自定义Sha256()方法返回十六进制格式的哈希字符串,再通过NSData.FromString()转成的NSData是字符串的UTF8编码结果,并非Apple要求的32字节原始SHA256二进制哈希值。
  • Specified argument was out of the range of valid values. (Parameter 'Platform name: 5.')是旧版本Xamarin.iOS对DCAppAttestService的平台枚举绑定bug,升级到Xamarin.iOS 15.0及以上稳定版本即可解决,传参正确时该异常不会复现。

DCDevice.CurrentDevice.GenerateTokenAsync()可正常执行,是因为该接口无强哈希格式校验,且不触发新版AppAttest相关的平台校验逻辑。

可正常运行的实现代码

注意计算哈希时直接返回原始二进制结果,不要转十六进制字符串:

using System;
using System.Security.Cryptography;
using System.Text;
using DeviceCheck;
using Foundation;

public async Task<byte[]> GetAttestObject(string Challenge)
{
    DCAppAttestService atserv = DCAppAttestService.SharedService;
    // AppAttest仅支持iOS14及以上版本的真实设备,模拟器永远返回Supported=false
    if (!atserv.Supported)
    {
        return null;
    }

    try
    {
        // 生成密钥对,生产环境需要将返回的keyId持久化存储,不要每次调用都重新生成
        var keyId = await atserv.GenerateKeyAsync();
        
        // 计算challenge的原始32字节SHA256哈希
        byte[] challengeRawBytes = Encoding.UTF8.GetBytes(Challenge);
        byte[] sha256Hash;
        using (SHA256 sha256 = SHA256.Create())
        {
            sha256Hash = sha256.ComputeHash(challengeRawBytes);
        }
        // 直接用原始哈希字节构造NSData,*禁止用NSData.FromString传入哈希字符串*
        NSData hashValue = NSData.FromArray(sha256Hash);
        
        // 执行密钥认证
        NSData attestResult = await atserv.AttestKeyAsync(keyId, hashValue);
        
        // 转换为字节数组返回
        byte[] resultBytes = new byte[attestResult.Length];
        System.Runtime.InteropServices.Marshal.Copy(attestResult.Bytes, resultBytes, 0, (int)attestResult.Length);
        return resultBytes;
    }
    catch (Exception ex)
    {
        // 可按需添加错误日志逻辑
        return null;
    }
}
注意事项
  • 测试必须使用真实iOS设备,系统版本不低于iOS14.0,模拟器不支持AppAttest服务
  • 需要提前在苹果开发者后台为对应App ID开启App Attest能力,同时在项目的Entitlements.plist中配置对应权限,否则会触发权限错误
  • 传入的Challenge值必须由服务端动态下发,禁止本地生成固定值,避免存在安全漏洞
  • 首次生成的keyId需要本地持久化保存,后续认证、断言操作都需要复用该keyId,重复生成密钥会导致服务端校验失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:54:15