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

Swift使用ECDH生成共享密钥时报公钥无效错误如何解决?

问题原因

你在生成本地公钥时主动移除了secp256r1非压缩公钥的标准前缀,而你调用的sharedSecret(forPublicKeyBase64:)方法要求传入的公钥必须带标准前缀,所以触发了无效公钥报错。

secp256r1的非压缩公钥标准格式为65字节:固定开头字节0x04 + 32字节X坐标 + 32字节Y坐标。你代码中let pub = Data(publicKey[1...publicKey.count-1])这行把开头的0x04前缀删除了,所以你发给服务器的是64字节的无前缀公钥,服务器返回给你的公钥也是同样去掉前缀的64字节格式,直接传给GMEllipticCurveCrypto的接口就会校验失败。

解决方法

在调用生成共享密钥的接口前,给服务器返回的公钥补上0x04前缀即可,修改后的generateSecret代码参考:

func generateSecret(withKey key: String) {
    guard let crypto = curveCrypto, let serverPubKeyData = Data(base64Encoded: key) else {
        return
    }
    // 补公钥前缀0x04
    var fullPubKeyData = Data([0x04])
    fullPubKeyData.append(serverPubKeyData)
    let fullPubKeyBase64 = fullPubKeyData.base64EncodedString()
    sharedKey = crypto.sharedSecret(forPublicKeyBase64: fullPubKeyBase64)
}

额外注意点

  • 你当前给服务器发的公钥已经去掉了前缀,只要服务器侧的解析逻辑是按64字节无前缀公钥处理的,就不需要调整发送逻辑,仅调整接收公钥的处理逻辑即可。
  • 如果后续需要切换为压缩公钥格式,需要同步修改compressedPublicKey属性,并且和服务器对齐压缩公钥的前缀规则(压缩公钥前缀为0x02或0x03,总长度33字节)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:09:02