在尝试从我在手持设备上运行的应用程序在本地网络上运行的服务器应用程序上调用 REST 方法时,它失败并显示“无法为 SSL/TLS 建立安全通道 ...System.Net.Sockets.SocketException: An现有连接被远程主机强行关闭”。
在 .NET 的更新/全功能版本中,您可以将此代码添加到客户端:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
...如图所示接受服务器的响应。不过,这在我的 Windows CE / Compact Framework 应用程序中对我不可用 - 尽管 ServicePointManager 是“已知数量”,但 ServerCertificateValidationCallback 不是。这显然是 Windows.NET 程序集的一部分,我在这个项目中不可用。
所以,假设仍然有办法完成同样的事情(接受 ssl 化服务器的响应),在这种情况下如何做到这一点?
一种建议的解决方法是向我的客户添加一个类,如下所示:
namespace HHS
{
using System.Net;
using System.Security.Cryptography.X509Certificates;
class TrustAllCertificatesPolicy : ICertificatePolicy
{
public TrustAllCertificatesPolicy()
{
}
public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req,
int problem)
{
return true;
}
}
}
...然后在应用程序启动时调用它(例如在主窗体的 Load() 事件中):
private void frmMain_Load(object sender, EventArgs e)
{
System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatesPolicy();
}
...但我的日志文件中仍然出现此异常:
Message: From FileXferREST.SendHTTPRequestNoCredentials(): Could not establish secure channel for SSL/TLS; Inner Ex: System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.ReceiveNoCheck(Byte[] buffer, Int32 index, Int32 request, SocketFlags socketFlags)
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Connection.System.Net.ISslDataTransport.Receive(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.SslConnectionState.ClientSideHandshake()
at System.Net.SslConnectionState.PerformClientHandShake()
at System.Net.Connection.connect(Object ignored)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
; Stack Trace: at System.Net.HttpWebRequest.finishGetRequestStream()
at System.Net.HttpWebRequest.GetRequestStream()
at HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
. . .
顺便说一句,TrustAllCertificatesPolicy 的(空)构造函数可能没有实际意义,因为它是灰色的。
服务器对客户端的期望究竟是什么?为什么服务器会强制关闭连接?
更新
在尝试确定客户端代码或服务器代码是否存在问题时,我尝试通过 Postman 访问 URL,但得到以下信息:
因此,我按照“在 Chrome 中导入 SSL 证书”链接查看是否有帮助。
[ http://blog.getpostman.com/index.php/2014/01/28/using-self-signed-certificates-with-postman/]告诉我:
原来有一个更好的解决方案可以解决这个问题,而且它也避免了每次启动浏览器时给 Chrome 添加异常。这就是你的做法:
1. Go to the root URL in your browser. For ex. https://localhost
2. Click on the lock icon on the top left in the URL bar.
. . .
但是,在进入https://localhost
Chrome 时,我得到“此网页不可用”
尝试http://localhost
代替(“http”而不是“https”),OTOH,我得到了一个“IIS7”图像,在一系列(人类)语言中带有“欢迎”。
至于第 2 步(“单击 URL 栏左上角的锁定图标。”),我在那里看不到这样的东西;这就是我所看到的:
那么我注定要失败了吗?