Using a Self-Signed Certificate with .Net's Httpwebrequest/Response

Using a self-signed certificate with .NET's HttpWebRequest/Response

@Domster: that works, but you might want to enforce a bit of security by checking if the certificate hash matches what you expect. So an expanded version looks a bit like this (based on some live code we're using):

static readonly byte[] apiCertHash = { 0xZZ, 0xYY, ....};

/// <summary>
/// Somewhere in your application's startup/init sequence...
/// </summary>
void InitPhase()
{
// Override automatic validation of SSL server certificates.
ServicePointManager.ServerCertificateValidationCallback =
ValidateServerCertficate;
}

/// <summary>
/// Validates the SSL server certificate.
/// </summary>
/// <param name="sender">An object that contains state information for this
/// validation.</param>
/// <param name="cert">The certificate used to authenticate the remote party.</param>
/// <param name="chain">The chain of certificate authorities associated with the
/// remote certificate.</param>
/// <param name="sslPolicyErrors">One or more errors associated with the remote
/// certificate.</param>
/// <returns>Returns a boolean value that determines whether the specified
/// certificate is accepted for authentication; true to accept or false to
/// reject.</returns>
private static bool ValidateServerCertficate(
object sender,
X509Certificate cert,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
// Good certificate.
return true;
}

log.DebugFormat("SSL certificate error: {0}", sslPolicyErrors);

bool certMatch = false; // Assume failure
byte[] certHash = cert.GetCertHash();
if (certHash.Length == apiCertHash.Length)
{
certMatch = true; // Now assume success.
for (int idx = 0; idx < certHash.Length; idx++)
{
if (certHash[idx] != apiCertHash[idx])
{
certMatch = false; // No match
break;
}
}
}

// Return true => allow unauthenticated server,
// false => disallow unauthenticated server.
return certMatch;
}

HttpWebRequest: Could not establish Trust Relationship for SSL - Self Signed Certificate already added to Trusted Root CA

I resolved this issue by changing the URL of the site I was trying to access the web service on.

By choosing a URL with the computer name (rather than local host), it accepted the certificate.

How do I use SSL certificates with HttpWebRequest in C#?

(Edit from our comments below)

I suppose what you need to do is create a custom class and store the data you need in it inside the delegate code, rather than pass around the actual certificate reference.

Trusting Self-Signed Certificate using HttpClient

SelfSigned CA has to be in LocalMachine\Root store on server and on any client connecting to the server.

SSL certificate should have exact DNS name that clients will use to connect to it. It can have several DNS names specified in the certificate in Subject alternative name (SAN) extension. In your case you are using IP address so either

  • you place the IP address in SAN or
  • you put the IP address in hosts file with DNS name you specified when issuing SSL certificate and use this DNS name in HttpClient

You might consider using XCA to issue your certificates. It has nice GUI and is built on top of OpenSSL. It has predefined templates for CA and SSL server. More info in documentation here.



Related Topics



Leave a reply



Submit