Swift与C#实现Diffie Hellman密钥交换时共享密钥不一致
iOS(Swift)与ASP.NET 8 Core间Diffie-Hellman密钥交换共享密钥不一致问题
我正在尝试在iOS(Swift)应用与ASP.NET 8 Core Web服务器间实现Diffie-Hellman密钥交换,但双方生成的共享密钥始终不一致。
已尝试的操作
- 确认iOS发送至服务器的公钥在接收后完全匹配;
- 确认服务器发送至iOS的公钥在接收后完全匹配;
- 尝试统一双方密钥格式(可能仍存在格式错误)。
工作流程
- iOS应用生成密钥对,将公钥发送至服务器;
- 服务器推导共享密钥,再将自身公钥返回给应用;
- iOS应用使用服务器公钥推导共享密钥,但双方结果不匹配。
Swift 代码(基于CryptoKit,测试环境iOS 17.6+)
class HandshakeHelper { // 创建密钥对 static func createKeyPairs() -> [String] { let privateKey = P256.KeyAgreement.PrivateKey() let privateKeyBase64 = privateKey.derRepresentation.base64EncodedString() let publicKeyBase64 = privateKey.publicKey.derRepresentation.base64EncodedString() // DER编码(X.509格式) return [privateKeyBase64, publicKeyBase64] } // 推导共享密钥:使用己方私钥和对方公钥生成共享密钥 static func deriveSharedSecret(ourPrivateKeyBase64: String, receivedPublicKeyBase64: String) -> String? { guard let privateKeyData = Data(base64Encoded: ourPrivateKeyBase64), let receivedPublicKeyData = Data(base64Encoded: receivedPublicKeyBase64) else { print("无效的密钥数据") return nil } do { // 重建己方私钥和接收的公钥 let privateKey = try P256.KeyAgreement.PrivateKey(derRepresentation: privateKeyData) let receivedPublicKey = try P256.KeyAgreement.PublicKey(derRepresentation: receivedPublicKeyData) // DER编码 // 推导共享密钥 let sharedSecret = try privateKey.sharedSecretFromKeyAgreement(with: receivedPublicKey) // 返回Base64格式的共享密钥 return sharedSecret.withUnsafeBytes { Data($0).base64EncodedString() } } catch { print("推导共享密钥出错: \(error)") return nil } } }
.NET 8 代码(基于System.Security.Cryptography)
public class HandshakeHelper { // 创建密钥对 public static List<string> CreateKeyPairs() { using var ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256); var privateKey = Convert.ToBase64String(ecdh.ExportECPrivateKey()); // PKCS#8格式 var publicKey = Convert.ToBase64String(ecdh.ExportSubjectPublicKeyInfo()); // X.509格式 File.WriteAllText("ecdh_priv.key", privateKey); File.WriteAllText("ecdh_pub.key", publicKey); return new List<string> { privateKey, publicKey }; } // 推导共享密钥:使用己方私钥和对方公钥生成共享密钥 public static string DeriveSharedSecret(string ourPrivateKeyBase64, string receivedPublicKeyBase64) { var privateKeyBytes = Convert.FromBase64String(ourPrivateKeyBase64); var receivedPublicKeyBytes = Convert.FromBase64String(receivedPublicKeyBase64); using var ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256); ecdh.ImportECPrivateKey(privateKeyBytes, out _); // 导入己方私钥 using var receivedPublicKey = ECDiffieHellman.Create(); receivedPublicKey.ImportSubjectPublicKeyInfo(receivedPublicKeyBytes, out _); // 导入接收的公钥 // 推导共享密钥 var sharedSecret = ecdh.DeriveKeyMaterial(receivedPublicKey.PublicKey); return Convert.ToBase64String(sharedSecret); // 返回Base64格式的共享密钥 } }
内容的提问来源于Stack Exchange,提问作者John Rams
相关产品推荐
相关产品推荐

