c# - Cómo ignorar la comprobación del certificado cuando ssl
httpwebrequest certificate (10)
Estoy tratando de encontrar una manera de ignorar la verificación de certificados cuando solicite un recurso Https, hasta el momento, encontré algunos artículos útiles en internet.
Pero todavía tengo un problema. Por favor revisa mi código. Simplemente no entiendo qué significa el código ServicePointManager.ServerCertificateValidationCallback
.
¿Cuándo se llamará este método delegado? Y una pregunta más, ¿en qué lugar debería escribir este código? Antes de ejecutar ServicePointManager.ServerCertificateValidationCallback
o antes Stream stream = request.GetRequestStream()
?
Por favor, ayúdame, gracias.
public HttpWebRequest GetRequest()
{
CookieContainer cookieContainer = new CookieContainer();
// Create a request to the server
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_remoteUrl);
#region Set request parameters
request.Method = _context.Request.HttpMethod;
request.UserAgent = _context.Request.UserAgent;
request.KeepAlive = true;
request.CookieContainer = cookieContainer;
request.PreAuthenticate = true;
request.AllowAutoRedirect = false;
#endregion
// For POST, write the post data extracted from the incoming request
if (request.Method == "POST")
{
Stream clientStream = _context.Request.InputStream;
request.ContentType = _context.Request.ContentType;
request.ContentLength = clientStream.Length;
ServicePointManager.ServerCertificateValidationCallback = delegate(
Object obj, X509Certificate certificate, X509Chain chain,
SslPolicyErrors errors)
{
return (true);
};
Stream stream = request.GetRequestStream();
....
}
....
return request;
}
}
Agregando las respuestas de Sani y blak3r, agregué lo siguiente al código de inicio de mi aplicación, pero en VB:
''** Overriding the certificate validation check.
Net.ServicePointManager.ServerCertificateValidationCallback = Function(sender, certificate, chain, sslPolicyErrors) True
Parece funcionar.
Como solo hay un ServicePointManager global, la configuración de ServicePointManager.ServerCertificateValidationCallback arrojará el resultado de que todas las solicitudes posteriores heredarán esta política. Como se trata de una "configuración" global, sería preferible configurarla en el método Application_Start en Global.asax .
Configurar la devolución de llamada anula el comportamiento predeterminado y usted mismo puede crear una rutina de validación personalizada.
De acuerdo con la respuesta de Adam y el comentario de Rob, utilicé esto:
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => certificate.Issuer == "CN=localhost";
que filtra el "ignorar" algo. Otros emisores se pueden agregar según sea necesario, por supuesto. Esto fue probado en .NET 2.0 ya que necesitamos soportar algún código heredado.
Esto funcionó para mí:
System.Net.ServicePointManager.ServerCertificateValidationCallback +=
delegate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true; // **** Always accept
};
Fragmento desde aquí: http://www.west-wind.com/weblog/posts/2011/Feb/11/HttpWebRequest-and-Ignoring-SSL-Certificate-Errors
Para cualquier persona interesada en aplicar esta solución por solicitud, esta es una opción y utiliza una expresión Lambda. La misma expresión de Lambda se puede aplicar también al filtro global mencionado por blak3r. Este método parece requerir .NET 4.5.
String url = "https://www..com";
HttpWebRequest request = HttpWebRequest.CreateHttp(url);
request.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
En .NET 4.0, la expresión de Lambda se puede aplicar al filtro global como tal
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
Se mencionó que antes de .NET 4.5, la propiedad solicitada para acceder a ServicePointManager
no estaba disponible.
Aquí está el código .NET 4.0 que le dará acceso al ServicePoint
por solicitud. No le da acceso a la devolución de llamada por solicitud, pero debería permitirle encontrar más detalles sobre el problema. Simplemente acceda a las scvPoint.Certificate
(o ClientCertificate
si lo prefiere).
WebRequest request = WebRequest.Create(uri);
// oddity: these two .Address values are not necessarily the same!
// The service point appears to be related to the .Host, not the Uri itself.
// So, check the .Host vlaues before fussing in the debugger.
//
ServicePoint svcPoint = ServicePointManager.FindServicePoint(uri);
if (null != svcPoint)
{
if (!request.RequestUri.Host.Equals(svcPoint.Address.Host, StringComparison.OrdinalIgnoreCase))
{
Debug.WriteLine(".Address == " + request.RequestUri.ToString());
Debug.WriteLine(".ServicePoint.Address == " + svcPoint.Address.ToString());
}
Debug.WriteLine(".IssuerName == " + svcPoint.Certificate.GetIssuerName());
}
Solo por cierto, esta es la manera menos detallada de desactivar toda validación de certificado en una aplicación determinada que conozco:
ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => verdadero;
También está la solución de delegado corto:
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
Tuve el mismo problema, así que creé una clase que ayuda con mis códigos. Pero usa un HttpClient:
https://github.com/PicolotoLF/IgnoresSSL
Ejemplo:
public async Task DoRequest()
{
IgnoreSSL Client = new IgnoreSSL();
var client = Client.IgnoreSSLA();
//NOTE(picoloto): Use how a HttpClient
var response = await client.GetAsync(URL)
}
Consejo: También puede usar este método para rastrear certificados que expiran pronto. Esto puede salvar su tocino si descubre un certificado que está a punto de caducar y puede arreglarlo a tiempo. Bueno también para compañías de terceros: para nosotros esto es DHL / FedEx. DHL solo deja que expire un certificado que nos está jodiendo 3 días antes de Acción de Gracias. Afortunadamente estoy a punto de arreglarlo ... ¡esta vez!
private static DateTime? _nextCertWarning;
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
if (error == SslPolicyErrors.None)
{
var cert2 = cert as X509Certificate2;
if (cert2 != null)
{
// If cert expires within 2 days send an alert every 2 hours
if (cert2.NotAfter.AddDays(-2) < DateTime.Now)
{
if (_nextCertWarning == null || _nextCertWarning < DateTime.Now)
{
_nextCertWarning = DateTime.Now.AddHours(2);
ProwlUtil.StepReached("CERT EXPIRING WITHIN 2 DAYS " + cert, cert.GetCertHashString()); // this is my own function
}
}
}
return true;
}
else
{
switch (cert.GetCertHashString())
{
// Machine certs - SELF SIGNED
case "066CF9CAD814DE2097D367F22D3A7E398B87C4D6":
return true;
default:
ProwlUtil.StepReached("UNTRUSTED CERT " + cert, cert.GetCertHashString());
return false;
}
}
}