CryptoKit.authenticationFailure问题求助:二号用户解密消息失败
解决CryptoKit.CryptoKitError.authenticationFailure解密失败问题
针对你遇到的一号用户解密正常、二号用户解密失败的问题,结合代码分析,核心原因大概率是双方生成的对称密钥不一致,以下是具体排查点和修复建议:
关键问题排查
1. 密钥协商配对顺序错误
密钥协商的核心逻辑是:
- 加密方(用户A):用自己的私钥 + 对方的公钥生成共享密钥
- 解密方(用户B):用自己的私钥 + 对方的公钥生成共享密钥
请检查二号用户的keysModel.publicUserKey是否确实存储了一号用户的公钥,而非自己的公钥。如果存储错误,双方生成的对称密钥会完全不同,直接导致解密验证失败。
2. 密钥导入方法存在隐患
importPrivateKey和importPublicKey的实现是否正确处理了密钥格式?比如:
- 私钥是否为PKCS#8格式,公钥是否为SPKI格式
- PEM格式的密钥是否正确去除了头尾标记(
-----BEGIN/END...-----)并完成Base64解码
如果密钥导入错误,生成的私钥/公钥实例无效,后续的共享密钥推导必然出错。
3. 固定Salt的潜在风险
prepareKeysPair中使用固定字符串作为HKDF的salt,虽然理论上双方一致就没问题,但如果字符串转Data时出现意外(比如编码环境差异),会导致salt不一致。建议直接用字节数组定义salt,避免字符串转码风险:
func prepareKeysPair(privateKey: P256.KeyAgreement.PrivateKey, publicKey: P256.KeyAgreement.PublicKey) throws -> SymmetricKey { // 直接用字节数组定义固定salt,避免字符串转Data的不确定性 let salt = Data([0x31, 0x34, 0x8c, 0x09, 0x87, 0xc7]) let sharedSecret = try privateKey.sharedSecretFromKeyAgreement(with: publicKey) let symmetricKey = sharedSecret.hkdfDerivedSymmetricKey( using: SHA256.self, salt: salt, sharedInfo: Data(), outputByteCount: 32 ) return symmetricKey }
4. 传输数据完整性问题
检查二号用户接收到的base64字符串是否和一号用户发送的完全一致,传输过程中如果数据被截断、篡改,会导致SealedBox实例无效,触发验证失败。
调试与修复建议
- 验证对称密钥一致性
在加密和解密时,打印对称密钥的哈希值,对比双方是否相同:
let symmetricKey = try prepareKeysPair(...) let keyData = symmetricKey.withUnsafeBytes { Data($0) } let keyHash = SHA256.hash(data: keyData) print("对称密钥哈希:\(keyHash)")
如果哈希值不同,重点排查私钥、公钥的存储和导入逻辑。
- 修复强制解包风险
解密时的String(data: decryptedData, encoding: .utf8)!存在崩溃风险,改为可选绑定:
guard let rSensitiveMessage = String(data: decryptedData, encoding: .utf8) else { completion(nil, NSError(domain: "DecryptionError", code: -1, userInfo: [NSLocalizedDescriptionKey: "解密数据无法转为字符串"])) return }
- 增加密钥有效性校验
在导入密钥后,添加校验逻辑,确保私钥/公钥实例有效:
let privateKey = try DatabaseManager.instance.importPrivateKey(keysModel.myPrivateKey) // 校验私钥是否能导出公钥,验证实例有效性 _ = privateKey.publicKey
内容的提问来源于stack exchange,提问作者Artem
相关产品推荐
相关产品推荐

