升级至.NET 6后连接TLS 1.1的MySQL数据库出现SSL认证错误
我有一个版本为MySQL 5.7.19、TLS版本为1.1的数据库,在.NET Core 3.1应用中使用以下代码可正常建立连接:
string connStr = "server=Myserver;user id=myuser;password=my password;database=db;SslMode=Required;SslCa=D:\\server-ca.pem;SslCert=D:\\client-cert.pem;SslKey=D:\\client-key.pem;"; try { using (MySqlConnection connection = new MySqlConnection(connStr)) { connection.Open(); connection.Close(); } } catch (Exception ex) { // handle the exception }
但升级到.NET 6后,代码抛出如下异常:
MySqlConnector.MySqlException(0x80004005): SSL Authentication Error
---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> System.ComponentModel.Win32Exception(0x8009030E): No credentials are available in the security package at System.Net.SSPIWrapper.AcquireCredentialsHandle(ISSPIInterface secModule, String package, CredentialUse intent, SCH_CREDENTIALS * scc) at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCH_CREDENTIALS * secureCredential) at System.Net.Security.SslStreamPal.AcquireCredentialsHandleSchCredentials(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer) at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer) --- End of inner exception stack trace --- at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(SslStreamCertificateContext certificateContext, SslProtocols protocols, EncryptionPolicy policy, Boolean isServer) at System.Net.Security.SecureChannel.AcquireClientCredentials(Byte[] & thumbPrint) at System.Net.Security.SecureChannel.GenerateToken(ReadOnlySpan1 inputBuffer, Byte[]& output) at System.Net.Security.SecureChannel.NextMessage(ReadOnlySpan1 incomingBuffer) at System.Net.Security.SslStream.ProcessBlob(Int32 frameSize) at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter adapter) at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm) at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions) at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ServerSession.cs:line 1539 at MySqlConnector.Core.ServerSession.InitSslAsync(ProtocolCapabilities serverCapabilities, ConnectionSettings cs, MySqlConnection connection, SslProtocols sslProtocols, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ServerSession.cs:line 1569 at MySqlConnector.Core.ServerSession.ConnectAsync(ConnectionSettings cs, MySqlConnection connection, Int32 startTickCount, ILoadBalancer loadBalancer, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ServerSession.cs:line 539 at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, String logMessage, Int32 startTickCount, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ConnectionPool.cs:line 403 at MySqlConnector.Core.ConnectionPool.ConnectSessionAsync(MySqlConnection connection, String logMessage, Int32 startTickCount, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ConnectionPool.cs:line 408 at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ConnectionPool.cs:line 98 at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, Int32 startTickCount, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/ConnectionPool.cs:line 128 at MySqlConnector.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int32 startTickCount, Activity activity, Nullable1 ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlConnection.cs:line 929 at MySqlConnector.MySqlConnection.OpenAsync(Nullable1 ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/MySqlConnection.cs:line 423 at MySqlConnector.MySqlConnection.Open() in /_/src/MySqlConnector/MySqlConnection.cs:line 382 at WebApplication1.Program.Main(String[] args) in D:\WebApplication1\WebApplication1\Program.cs:line 24
请问.NET 6是否存在相关重大变更导致该问题?若没有,烦请提供解决该错误的建议。
补充说明:
上述数据库版本由一位终端用户使用,且用户不愿升级。因此我需要查找官方文档来确认该版本是否未被官方支持。
一、.NET 6的相关重大变更
.NET 6对TLS协议支持做了严格限制:
- 默认禁用了TLS 1.0和TLS 1.1,仅启用TLS 1.2及以上版本,这是因为TLS 1.1存在安全漏洞,属于已弃用协议。
- 同时,.NET 6中的
SslStream在处理客户端证书时的逻辑有调整,对旧版TLS协议下的证书认证兼容性下降。
你的数据库使用TLS 1.1,正好命中了这个变更,这是连接失败的核心原因。
二、解决建议
1. 显式启用TLS 1.1支持
在应用启动时添加代码,允许使用旧版TLS协议:
// 在Program.cs初始化代码中添加 AppContext.SetSwitch("System.Net.Security.SslStream.AllowLegacyTlsVersions", true);
同时,可通过连接字符串构建器明确指定TLS版本:
var builder = new MySqlConnectionStringBuilder(connStr) { SslProtocols = SslProtocols.Tls11 }; using (var connection = new MySqlConnection(builder.ConnectionString)) { connection.Open(); }
2. 检查证书格式与权限
- 确认客户端证书(
.pem文件)格式无损坏,符合.NET 6的读取要求。 - 检查应用运行账号对证书文件的读取权限,Windows环境可通过文件ACL设置确保权限正常。
3. 调整MySqlConnector版本
尝试使用兼容.NET 6且对旧TLS协议支持更好的MySqlConnector版本,注意选择与.NET 6兼容的较低版本包。
三、官方支持性确认
- MySQL 5.7系列的扩展支持已于2023年10月31日结束,官方不再提供任何更新和技术支持。
- .NET 6官方文档未明确禁止连接MySQL 5.7,但由于MySQL 5.7已停止支持、TLS 1.1为弃用协议,官方不推荐该组合,也不会针对此类场景提供修复。
内容的提问来源于stack exchange,提问作者janarthanan

