异常: 底层连接已关闭: 无法建立 SSL/TLS 安全通道的信任关系

5

针对Firebase通知代码

WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send"); 
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new{collapse_key = "unassigned", to = deviceToken,data = new
  {body = message,title = title,sound = "default"}
};

用于在移动设备上通知的消息

var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationId));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
tRequest.ContentLength = byteArray.Length;

以下代码出现错误

using (Stream dataStream = tRequest.GetRequestStream())
{ 
  dataStream.Write(byteArray, 0, byteArray.Length);
 using (WebResponse tResponse = tRequest.GetResponse())
  { 
    using (Stream dataStreamResponse = tResponse.GetResponseStream())
    { 

   //code 1
    }     
  }   
}  

使用(StreamReader tReader = new StreamReader (dataStreamResponse)) { String sResponseFromServer = tReader.ReadToEnd(); string str = sResponseFromServer; } - Bhhruguni
这段代码在本地可以正常工作,但在服务器上无法工作。 - Bhhruguni
在服务器上安装Windows Server 2003 R2操作系统和IIS 6。 - Bhhruguni
在服务器上托管Web服务后,无法工作的通知......请帮帮我。提前谢谢您。 - Bhhruguni
4个回答

14

标题中的异常表示您正在连接具有TLS加密的端点,并且该端点公开的证书未获得您的信任。这意味着它没有使用您的CA(证书颁发机构)存储中的证书进行签名,例如自签名证书。

如果证书是自签名的,可以将其添加到您的CA存储中。否则,您可以尝试使用浏览器导航到端点,并查找端点呈现的证书的副本,以手动信任它。(请注意,通过这样做,如果端点已被攻击者入侵,则您会手动信任其证书。)

您还可以通过添加一个始终返回有效(true)的自定义证书验证处理程序来避免此检查。但是,请注意,这样做将使您暴露于中间人攻击,因为您将失去检查端点真实性的能力

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

1
你能详细解释一下以便理解吗? - Bhhruguni
任何其他选项...从服务器调用Web服务时出现错误。但是当我从本地机器执行时,它可以正常工作。 - Bhhruguni
我猜你在本地机器上安装了一个证书,用于“验证”终端公开的证书,但是你的服务器没有。此外,如果你将应用程序作为本地系统服务启动,而不是控制台应用程序或类似应用程序,则证书存储会有所不同。 - Pablo Recalde

1

我不知道为什么要使用上面所述的这行代码

ServicePointManager
    .ServerCertificateValidationCallback += 
    (sender, cert, chain, sslPolicyErrors) => true;

我无法使其工作。
但是,使用这种方式可以正常工作:
internal static bool ValidateServerCertificate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    return true;
}
ServicePointManager.ServerCertificateValidationCallback  = ValidateServerCertificate;

很可能你使用的C#版本不支持以lambda形式编写事件处理程序。 - Pablo Recalde

1
调用 Web 和 API 站点应具有相同的 SSL 证书。我使用“ IIS Express Development Certificate”。 将您的证书导出到本地文件(导出证书)。 将您的证书导入“ ConsoleCertificate” 中的“ Trusted Root Certification Authorities” 文件夹。 将其导入信任根

-1

这对我有用。

ServicePointManager
  .ServerCertificateValidationCallback += 
  (sender, cert, chain, sslPolicyErrors) => true;

我进行了数次测试,有时使用它,有时不使用它。肯定解决了这个问题。


1
它并不“解决”问题,而是将问题隐藏起来,使您的应用程序容易受到攻击。 - Pablo Recalde
幸运的是,我能够远离需要这个修复的代码。 - Bill Pothen

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