gpt4 book ai didi

c# - Unity TlsException : Handshake failed UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED

转载 作者:行者123 更新时间:2023-12-03 20:11:36 36 4
gpt4 key购买 nike

我正在尝试更新我的应用程序的 TcpClient将 TLS 与 SslStream 一起使用而不是正常的Stream ,我为此使用的代码似乎在 Unity 之外工作,但在集成到我的 Unity 2019.1.8(也在 2018 年和 2017 年测试)项目时失败。

建立连接并打开一个新的SslStream我使用以下代码:

public static void InitClient(string hostName, int port, string certificateName)
{
client = new TcpClient(hostName, port);

if (client.Client.Connected)
{
Debug.LogFormat("Client connected succesfully");
}
else
{
Debug.LogErrorFormat("Client couldn't connect");
return;
}

stream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

try
{
stream.AuthenticateAsClient(certificateName);
}
catch (AuthenticationException e)
{
Debug.LogErrorFormat("Error authenticating: {0}", e);
if (e.InnerException != null)
{
Debug.LogErrorFormat("Inner exception: {0}", e);
}
Debug.LogErrorFormat("Authentication failed - closing connection");
stream.Close();
client.Close();
}
}

并用于验证证书

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;

Debug.LogErrorFormat("Certificate error: {0}", sslPolicyErrors);
return false;
}

在 Unity 2019.1.8 中,客户端连接并尝试验证远程证书,但失败并出现错误 TlsException: Handshake failed - error code: UNITYTLS_INTERNAL_ERROR, verify result: UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED.
制作 ValidateServerCertificate总是返回 true让我的客户毫无问题地连接。

我尝试使用完全相同的代码在面向 .net 框架 4.7.1 的独立 C# 控制台应用程序中复制该问题。在此应用程序中启动客户端将返回 true来自 ValidateServerCertificate来自 sslPolicyErrors == SslPolicyErrors.None查看。

我知道该证书是由受信任的 CA 颁发的有效证书(已通过控制台应用程序接受该证书并且在浏览器中具有挂锁这一事实进行了验证)。

为什么验证在 Unity 中失败,但在其他地方没有?

最佳答案

为什么 Unity 无法验证选项 1:
尽管证书有效且正确(例如,它在 Web 浏览器中使用时有效),但它不包括到根 CA 的中间证书链。这导致无法形成信任链(Unity 不缓存/检索中间体),导致 UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED标志被设置。
为了解决这个问题,我需要将证书链附加到我的叶证书,以便 Unity 可以验证整个链直到根 CA。要查找证书的证书链,您可以使用“TLS 证书链编写器”。
根据您使用的软件,您可能需要将链包含在证书中,或者将其保存在单独的文件中。来自 whatsmychaincert (我绝不隶属于这个网站,只是使用它):

Note: some software requires you to put your site's certificate (e.g. example.com.crt) and your chain certificates (e.g. example.com.chain.crt) in separate files, while other software requires you to put your chain certificates after your site's certificate in the same file.


为什么 Unity 无法验证选项 2:
当您的服务器的 SSL 证书过期时,Unity 将抛出完全相同的 UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED没有证书已过期的附加信息的错误,因此请确保“有效期至”日期在将来(这也会导致证书在 Web 浏览器中使用时被拒绝)。

为什么浏览器/控制台应用程序可以验证:
软件在处理不完整链的方式上可以有不同的实现。它可以抛出错误,说明链已损坏,因此不可信(如 Unity 的情况),或缓存并保存中间体以供以后使用/从以前的 session 中检索它(如浏览器和 Microsoft 的 .net (核心)做)。
this answer 中所述(强调我的)

In general, SSL/TLS clients will try to validate the server certificate chain as received from the server. If that chain does not please the client, then the client's behaviour depends on the implementation: some clients simply give up; others (especially Windows/Internet Explorer) will try to build another chain using locally known intermediate CA and also downloading certificates from URL found in other certificates (the "authority information access" extension).



如 [answer to issue 1115214][3] 所述,在未提供链时不信任证书是 Unity 出于跨平台兼容性而做出的深思熟虑的决定:

We may be able to solve this issue by doing a verification via the system specific TLS api instead of using OpenSSL/MbedTLS to validate against root certificates as we do today, however this solution would then not work cross-platform. So we don't want to implement it today, as it would hide the misconfigured server from the user on some but not all platforms.



在提出这个问题时,我发现这是针对我的特殊情况的解决方案,因此决定自行回答以供将来引用。然而 UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED可能有各种原因,这只是其中之一。

关于c# - Unity TlsException : Handshake failed UNITYTLS_X509VERIFY_FLAG_NOT_TRUSTED,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59945581/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com