【问题标题】:ssl handshake error when running dotnet ef database update command运行 dotnet ef 数据库更新命令时出现 ssl 握手错误
【发布时间】:2023-01-30 08:47:41
【问题描述】:

我已经在我的 asp.net 项目中成功添加了带有 dotnet ef migrationsa add 的迁移脚本。 我有 Arch Linux,

关于VS代码:

Version: 1.74.3
Commit: 97dec172d3256f8ca4bfb2143f3f76b503ca0534
Date: 2023-01-11T09:00:07.949Z
Electron: 19.1.9
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Linux x64 6.0.10-arch2-1
Sandboxed: No

当我想更新数据库时:

dotnet ef database update -c PersistedGrantDbContext

我有以下错误:

构建开始... 构建成功。 Microsoft.Data.SqlClient.SqlException (0x80131904): 已成功与服务器建立连接,但在预登录握手期间发生错误。 (提供商:SSL 提供商,错误:31 - 加密(ssl/tls)握手失败) ---> System.IO.IOException: 从传输流中收到意外的 EOF 或 0 字节。 在 System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](CancellationToken cancellationToken) 在 System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst,Byte[] reAuthenticationData,CancellationToken cancellationToken) 在 System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions) 在 Microsoft.Data.SqlClient.SNI.SNITTCPHandle.EnableSsl(UInt32 选项) 在 Microsoft.Data.SqlClient.SNI.TdsParserStateObjectManaged.EnableSsl(UInt32& 信息,布尔 tlsFirst) 在 Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常、Boolean breakConnection、Action1 wrapCloseInAction) at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at Microsoft.Data.SqlClient.TdsParser.EnableSsl(UInt32 info, SqlConnectionEncryptOption encrypt, Boolean integratedSecurity) at Microsoft.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(SqlConnectionEncryptOption encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean&amp; marsCapable, Boolean&amp; fedAuthRequired, Boolean tlsFirst) at Microsoft.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnectionString connectionOptions, Boolean withFailover) at Microsoft.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover) at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance) at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken, DbConnectionPool pool) at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource1 重试、DbConnectionOptions userOptions、DbConnectionInternal oldConnection、DbConnectionInternal& 连接) 在 Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection,DbConnectionFactory connectionFactory,TaskCompletionSource1 retry, DbConnectionOptions userOptions) at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource1 重试,DbConnectionOptions userOptions) 在 Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource1 retry, SqlConnectionOverrides overrides) at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.OpenDbConnection(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.&lt;&gt;c__DisplayClass18_0.&lt;Exists&gt;b__0(DateTime giveUp) at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.&lt;&gt;c__DisplayClass12_02.b__0(DbContext _,TState s) 在 Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState 状态,Func3 operation, Func3 verifySucceeded) 在 Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy 策略,TState 状态,Func2 operation, Func2 verifySucceeded) 在 Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists(布尔 retryOnNotExists) 在 Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists() 在 Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists() 在 Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(字符串 targetMigration) 在 Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(字符串 targetMigration、字符串连接字符串、字符串上下文类型) 在 Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(字符串 targetMigration、字符串连接字符串、字符串上下文类型) 在 Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0() 在 Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(动作动作) ClientConnectionId:461d4248-1aeb-4d6c-8964-f7864a2468c9 已成功与服务器建立连接,但在登录前握手期间发生错误。 (提供商:SSL 提供商,错误:31 - 加密(ssl/tls)握手失败)

这是我的连接字符串和 PersistedGrantDbContextFactory.cs

using Duende.IdentityServer.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace IdentityServer.Database
{
    public class PersistedGrantDbContextFactory : IDesignTimeDbContextFactory<PersistedGrantDbContext>
    {
        private readonly IConfiguration? _configuration;
        public PersistedGrantDbContextFactory()
        {
            _configuration = null;
        }
        public PersistedGrantDbContextFactory(IConfiguration configuration)
        {
            _configuration = configuration;
        }
        PersistedGrantDbContext IDesignTimeDbContextFactory<PersistedGrantDbContext>.CreateDbContext(string[] args)
        {           
            string? cs = _configuration.GetConnectionString("Identity01");
            string? assemblyName = typeof(PersistedGrantDbContextFactory).Assembly.GetName().Name;

            var optionsBuilder = new DbContextOptionsBuilder<PersistedGrantDbContext>();
            optionsBuilder.UseSqlServer(cs);

            IServiceCollection services = new ServiceCollection();

            services.AddIdentityServer()
                    .AddOperationalStore(options =>
                    {
                        options.ConfigureDbContext = b => b.UseSqlServer(cs, sqlOptions =>
                        {
                            sqlOptions.MigrationsAssembly(assemblyName);
                        });
                    });

            optionsBuilder.UseApplicationServiceProvider(services.BuildServiceProvider());

            var context = new PersistedGrantDbContext(optionsBuilder.Options);
            return context;
        }
    }
}

我的连接字符串:

"Data Source=ip,port;Initial Catalog=IdentityDb;Integrated Security=False;Persist Security Info=True;User ID=userName;Password=pass;Pooling=False;Encrypt=False;TrustServerCertificate=True;Connection Timeout=30;MultipleActiveResultSets=True;App=EntityFramework;"
  • 我部署的 asp.net 没有任何问题,与数据库的连接也没有问题。
  • 我也有mssql vs 代码扩展的 ssl 错误

【问题讨论】:

  • TLS 在发送 HTTP 请求以建立加密密钥之前执行。如果 TLS 失败,则永远不会发送 HTTP 请求。在 Net Library 中,TLS 在 4.7.2 版之前的 Net 中执行。 4.7.2之后Net由OS执行,但是csproj中有一个选项仍然可以在Net中执行TLS。许多 4.7.2 之前的应用程序都将 OpenSSL 用于 TLS,因为 Net 不支持所有的加密模式。 OpenSSL 也被非 Net 应用程序用于 TLS 而不是 OS。有太多的组合让我无法从这篇文章中看出为什么有些代码有效而其他代码无效。
  • @jdweng 解决这个问题你需要知道什么?告诉我提供它。因为有些日子我有这个问题
  • 我给了你我所知道的一切。我不知道你的版本、操作系统、OpenSSL。
  • 检查这个:stackoverflow.com/q/66445221/5311735。猜猜你的 sql server 不支持 TLS 1.2。该答案也提供了其他选择。

标签: c# asp.net .net entity-framework ssl


【解决方案1】:

错误消息表明在尝试与服务器建立连接时 SSL/TLS 握手存在问题。这可能是由多种原因引起的,例如服务器配置不正确或使用的 SSL 证书存在问题。一种可能的解决方案是检查服务器的配置并确保所使用的 SSL 证书有效且配置正确。此外,您可以尝试在您的服务器上禁用 SSL 加密,看看是否可以解决问题。

【讨论】:

    【解决方案2】:

    据我所知

    System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream. at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](CancellationToken cancellationToken)
    

    是罪魁祸首,您在握手后立即结束文件, 我建议研究可以作为同步打开并作为异步执行的连接,尝试使用同步方法,看看它是否有帮助。

    可能是服务器不接受的 TLS 版本。

    如果没有特定软件版本的列表,我将无法进一步帮助您。

    【讨论】:

    • 我可能弄错了,但是如果 TLS 失败,它不会立即发回 EOF 吗?我希望 EOF 是初始故障的陡峭而不是导致故障。
    • 确实如此,我可能是错的,但在这种情况下我不能确定它的 TLS 失败并且在过去我遇到了一个问题,它在连接后返回和 EOF,结果是对服务器的异步调用与同步连接,因此我为什么那样说
    猜你喜欢
    • 2021-05-25
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多