SSL证书验证 - 是否涉及到任何缓存?

4
案例:
几天前,我们的集成伙伴错过了更改SSL服务器证书的截止日期,证书的有效期为两天前。
当这种情况发生时,我们的客户端软件开始抛出异常:“根据验证程序,远程证书无效”。我们的客户端软件是用.NET 4编写的,在Windows Server 2012上运行。 SSL调用是通过WCF堆栈完成的。
昨天下午,我们的集成合作伙伴安装了一个新的有效SSL证书。
问题现在是,我们仍然在客户端上收到相同的异常:“根据验证程序,远程证书无效”。
我的问题:
SSL证书验证状态是否在客户端以某种方式被缓存?我们的客户端软件是长时间运行的进程,很少重新启动。
或者这是SSL协议的固有部分吗?我对SSL或网络不是专家,但它不是真的a)仅在SSL握手期间才由客户端检查服务器证书,并且b)在SSL握手中交换的信息可以用于多个对同一服务器的网络请求?如果确实如此,那么SSL握手的有效期是如何定义的?
更新: 我们重新启动了客户端进程,然后它就正常工作了。对我来说,这表明在客户端上缓存了一些SSL服务器证书验证状态,每个进程一个。我仍然非常想了解更多关于此的详细信息:发生在哪个堆栈层次? WCF? .NET? Windows API?这个缓存持续多长时间?是否有办法调整缓存行为?我可以手动清空缓存吗?这在哪里有记录?
完整的堆栈跟踪:
[E0]: The remote certificate is invalid according to the validation procedure. 
[T0]: System.Security.Authentication.AuthenticationException    at 
System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, 
AsyncProtocolRequest asyncRequest, Exception exception)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, 
AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] 
buffer, AsyncProtocolRequest asyncRequest)     at 
System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)  
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext 
executionContext, ContextCallback callback, Object state, Boolean 
preserveSyncCtx)     at System.Threading.ExecutionContext.Run(ExecutionContext 
executionContext, ContextCallback callback, Object state, Boolean 
preserveSyncCtx)     at System.Threading.ExecutionContext.Run(ExecutionContext 
executionContext, ContextCallback callback, Object state)     at 
System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)     at 
System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)     at 
System.Net.ConnectStream.WriteHeaders(Boolean async) [E1]: The underlying 
connection was closed: Could not establish trust relationship for the SSL/TLS 
secure channel. [T1]: System.Net.WebException    at 
System.Net.HttpWebRequest.GetResponse()     at 
System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannel
Request.WaitForReply(TimeSpan timeout) [E2]: Could not establish trust 
relationship for the SSL/TLS secure channel with authority 
'***removed***'. [T2]: 
System.ServiceModel.Security.SecurityNegotiationException 

1
这个错误并不一定表示与吊销检查有关。除了吊销检查之外,还有很多检查可能会失败。您能提供更多关于错误的细节吗? - Crypt32
证书无效(已过有效期),未被吊销。 - codeape
我包含了完整的堆栈跟踪。 - codeape
堆栈跟踪没有提供足够的信息,但我怀疑证书链不受信任,因为根证书可能未被信任或缺失。 - Crypt32
我不认为证书链信任是问题,因为在客户端进程重新启动后它可以正常工作(请参见原始问题中的更新)。 - codeape
1个回答

5
我遇到了相同的问题。我正在使用本地根证书验证TLS。如果我从存储中删除了该证书,连续的请求(使用HttpWebRequest)将继续进行验证,只要每几秒钟就进行一次调用。但是,如果我等待了短时间(30-60秒),下一次调用会因找不到根证书而失败。
将HttpWebRequest.KeepAlive属性设置为false以防止缓存。要获得更多控制权,看起来您必须开始反射下去。请参见问题如何清除客户端.NET SSL会话缓存

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接