Unity 2021.3.5f1中SSL服务器证书加载及Unity Transport问题求助
Unity 2021.3.5f1 SSL服务器搭建:X509Certificate2加载及相关问题修复方案
针对你遇到的三个问题,分别给出可落地的修复方案:
1. PFX证书加载抛出FormatException的修复
该异常源于Mono runtime对PFX格式的解析限制,尤其是OpenSSL生成的证书可能使用了Mono不支持的加密算法或格式。
- 重新生成兼容的PFX证书:使用OpenSSL的
-legacy参数生成证书,确保兼容旧版Mono:
注意:必须包含完整证书链(openssl pkcs12 -export -in cert.pem -inkey key.pem -out server.pfx -certfile chain.pem -legacy -passout pass:your_password-certfile chain.pem),避免链缺失导致解析错误。 - 调整加载参数:加载证书时指定存储标志,绕过权限和解析限制:
var cert = new X509Certificate2( "Assets/Resources/server.pfx", "your_password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet ); - 验证证书有效性:用Windows证书管理器导入PFX,确认无格式错误后再导出(选择PKCS#12格式,勾选导出私钥及完整证书链)。
2. rsa.ImportPkcs8PrivateKey抛出PlatformNotSupported的修复
Unity 2021.3的Mono runtime未实现ImportPkcs8PrivateKey方法,需改用兼容的私钥加载方式:
- 转换私钥格式:将PKCS8私钥转为XML格式(用.NET Core工具完成,避免在Unity中处理):
- 先将PKCS8转PEM:
openssl pkcs8 -topk8 -inform PEM -in private_key.p8 -outform PEM -nocrypt -out private_key.pem - 用.NET Core程序生成XML格式私钥:
using System.Security.Cryptography; using System.IO; var rsa = RSA.Create(); rsa.ImportFromPem(File.ReadAllText("private_key.pem")); File.WriteAllText("private_key.xml", rsa.ToXmlString(true));
- 先将PKCS8转PEM:
- 在Unity中加载XML私钥:
需确保项目引用var rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(File.ReadAllText("Assets/Resources/private_key.xml")); // 关联私钥到证书 var cert = new X509Certificate2("Assets/Resources/cert.cer"); var certWithKey = cert.CopyWithPrivateKey(rsa);System.Security.Cryptography.Xml命名空间。
3. Unity Transport 1.0.0中WithSecureServerParameters不存在的修复
Unity Transport 1.0.0未提供该API,有两种替代方案:
- 升级Transport兼容版本:在Package Manager中升级Unity Transport到1.1.0及以上(确认版本兼容Unity 2021.3.5f1),新版本已支持
WithSecureServerParameters。 - 手动实现SSL层:放弃Transport的SSL封装,用
TcpListener结合SslStream搭建加密服务器:
注意:仅使用using System.Net; using System.Net.Sockets; using System.Net.Security; using System.Security.Cryptography.X509Certificates; var listener = new TcpListener(IPAddress.Any, 443); listener.Start(); while (true) { using var client = listener.AcceptTcpClient(); using var sslStream = new SslStream(client.GetStream(), false); try { sslStream.AuthenticateAsServer( cert, // 之前加载的带私钥的X509Certificate2 false, SslProtocols.Tls12, true ); // 在此处理sslStream的读写逻辑 } catch (Exception ex) { sslStream.Close(); client.Close(); } }SslProtocols.Tls12或Tls13,避免过时协议带来的安全问题。
内容的提问来源于stack exchange,提问作者aarelovich
相关产品推荐
相关产品推荐

