Using System.Net.WebClient with HTTPS certificate

2020-05-26 14:06发布

问题:

In my C# Windows client, I have a POST submission to "the mothership". I want the data in the submits to be secured, of course, so I paid for HostGator to issue me an SSL certificate.

I saved off the .CER file, and I'm constructing the request as such:

//wrapper for WebClient object to use certificate file
class SecureWebClient : WebClient
{
    protected override WebRequest GetWebRequest(Uri address)
    {
        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
        string certPath = @"e:\mycertificate.cer";
        X509Certificate myCert = X509Certificate.CreateFromCertFile(certPath);
        request.ClientCertificates.Add(myCert);
        return request;
    }
}

//request
private static SecureWebClient client = new SecureWebClient();
private static NameValueCollection = new NameValueCollection();
nvc.Add(POST_ACTION, ACTION_CODE_LOGIN);
nvc.Add(POST_EMAIL, email);
nvc.Add(POST_PASSWORD, password);

sResponse = System.Text.Encoding.ASCII.GetString(client.UploadValues(BASE_URL + ACTION_PAGE, nvc));

Its throwing a System.Net.WebException:

The underlying connection was closed: An unexpected error occurred on a send.

The InnerException is a System.IO.IOException:

The handshake failed due to an unexpected packet format.

Any insight on what I am doing wrong?

回答1:

If you're not using client certificates and you can access your server using https:// then your code should look like:

private static WebClient client = new WebClient();
private static NameValueCollection nvc= new NameValueCollection();

nvc.Add(POST_ACTION, ACTION_CODE_LOGIN);
nvc.Add(POST_EMAIL, email);
nvc.Add(POST_PASSWORD, password);

sResponse = System.Text.Encoding.ASCII.GetString(client.UploadValues(BASE_URL + ACTION_PAGE, nvc));

As long as your BASE_URL uses https:// then all the data (to and from the server) will be encrypted.

IOW using SSL/TLS from a client to a server does not require the client to do anything special (with the certificate), besides using https:// as the scheme, since the operating system provides everything (e.g. trusted roots) you need to secure the data transmission.



回答2:

Client certificates will work only if the private key is available. This is not generally the case when using .cer files since the X.509 certificate does not include the private key.

The only safe way to ensure the private key is available is to load the certificate from a PKCS#12 file where both the certificate(s) and the private key are available (i.e. both were exported into the .pfx file).

Notes:

  • I said generally because Windows/CryptoAPI sometimes does some magic (when used with X509Certificate) and automatically associate a certificate with a private key from the certificate.key stores.

  • I said safe because that will work on Mono too, not just MS .NET.



回答3:

Sounds like you are doing it backwards. You should have the SLL Certificate installed on the web host/server. Then you create a web request to web server and requires the HTTPS protocol.



回答4:

Just connect to your server with RDP

Open IE and go to Internet Options

Navigate to Advanced Tab and Enable both Use SSL 2.0 and SSL 3.0

Now your server requests will be authenticated