通过WSS连接时无法创建SSL / TLS安全通道,仅在Azure

时间:2018-01-23 17:48:55

标签: asp.net ssl asp.net-web-api websocket azure-web-sites

我正在构建一个Web Api(使用ASP.NET Web API),它通过Secure WebSockets连接到我们的客户端公开的端点(wss://client-domain:4747/app/engineData)。他们以.pem格式(root.pemclient.pem)以及私钥(client_key.pem)向我提供了证书。

为了完成这项工作,我做了以下工作:

1)将client.pemclient_key.pem转换为单个.pfx文件(在此处使用:Convert a CERT/PEM certificate to a PFX certificate

2)我使用了库System.Net.WebSockets,并编写了以下代码:

private void InitWebSockesClient()
{
    client = new ClientWebSocket();
    client.Options.SetRequestHeader(HEADER_KEY, HEADER_VALUE); //Some headers I need
    AddCertificatesSecurity();
}

private void AddCertificatesSecurity()
{
     ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
         | SecurityProtocolType.Tls11
         | SecurityProtocolType.Tls12;

     // I KNOW THIS SHOULDNT BE USED ON PROD, had to use it to make it 
     // work locally.
     ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

      X509Certificate2 x509 = new X509Certificate2();
      // this is the pfx I converted from client.pem and client_key
      byte[] rawData = ReadFile(certificatesPath + @"\cert.pfx");
      x509.Import(rawData, "123456", X509KeyStorageFlags.UserKeySet);

      X509Certificate2Collection certificateCollection = new X509Certificate2Collection(x509);

      client.Options.ClientCertificates = certificateCollection;
 }

当我想要连接时,我打电话:

 public async Task<bool> Connect()
 {
    Uri uriToConnect = new Uri(URL);
    await client.ConnectAsync(uriToConnect, CancellationToken.None);
    return client.State == WebSocketState.Open;
 }

这在本地工作正常。但每当我在Azure(App Service)上部署我的Web Api并向其发出HTTP请求时,它都会抛出:

System.Net.WebSockets.WebSocketException - Unable to connect to the remote server.

内在的例外:

System.Net.WebException - The request was aborted: Could not create SSL/TLS secure channel.

我在AppService实例上启用了WebSockets。

如果我删除总是为证书验证返回true的行,它甚至在本地也不起作用,并且消息说明如下:

The remote certificate is invalid according to the validation procedure.

所以肯定我的证书有问题,这三个.pem文件现在正在一个类似的[![在此处输入图像描述] [1]] [1]应用程序中使用node.js并正常工作,WSS连接正确建立。我真的不知道每个人的用法是什么,所以我有点迷失在这里。

这些是我想要连接的域的密码套件:https://i.stack.imgur.com/ZFbo3.png

1 个答案:

答案 0 :(得分:1)

受汤姆评论的启发,我终于通过在Azure App Service中将证书添加到Web App而不是尝试从文件系统中使用它来使其工作。首先,我将.pfx文件上载到Azure的SSL证书部分。然后,在应用程序设置中,我添加了一个名为WEBSITE_LOAD_CERTIFICATES的设置,其中包含我想要的证书(.pfx)的指纹。

之后,我修改了我的代码来做这样的工作:

private void InitWebSockesClient()
{
     client = new ClientWebSocket();
     client.Options.SetRequestHeader(HEADER_KEY, HEADER_VALUE); //Some headers I need
     AddCertificateToWebSocketsClient();
}

private void AddCertificateToWebSocketsClient()
{
     ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11
                        | SecurityProtocolType.Tls12;

     // this should really validate the cert
     ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; 

    // reading cert from store
    X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    certStore.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certCollection = 
           certStore.Certificates.Find(X509FindType.FindByThumbprint,
                            CERTIFICATES_THUMBPRINT,
                            false);

     if (certCollection.Count > 0)
     {
         client.Options.ClientCertificates = certCollection;
     }
     else
     {
         // handle error
     }
     certStore.Close();
}

CERTIFICATES_THUMBPRINT是一个字符串(证书的指纹图,即您在Azure上看到的那个)。

如果您想让它在本地运行,您只需要在您的计算机上安装证书,否则它很难在商店中找到它。

Azure文档中对所有这些内容的引用:https://docs.microsoft.com/en-us/azure/app-service/app-service-web-ssl-cert-load