Cómo enviar un certificado de cliente mediante las clases HttpWebRequest y HttpWebResponse en Microsoft Visual C# .NET

Seleccione idioma Seleccione idioma
Id. de artículo: 895971 - Ver los productos a los que se aplica este artículo

Requisitos

Para enviar un certificado de cliente desde las aplicaciones Microsoft ASP.NET, debe tener service Pack instalado las revisiones siguientes:

Microsoft .NET framework 1.0

Debe instalar .NET Framework 1.0 Service Pack 3 (SP3) o debe instalar el hotfix 817854.Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
817854REVISIÓN: La aplicación Web ASP.NET no puede entregar un certificado de cliente a un sitio Web con seguridad mejorada

.NET framework 1.1

Debe instalar .NET Framework 1.1 Service Pack 1 (SP1) o debe instalar el hotfix 831138.Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
831138REVISIÓN: Una aplicación de .NET Framework que utiliza el método System.NET.WebRequest muy frecuentemente experimenta errores OutOfMemoryException
Expandir todo | Contraer todo

En esta página

INTRODUCCIÓN

Se explica cómo enviar un certificado de cliente con las clases HttpWebRequest y HttpWebResponse en Microsoft Visual C#. NET.

Más información

Puede enviar un certificado de cliente cuando el servidor Web requiere uno mediante el HttpWebRequest y las clases HttpWebResponse . Para obtener un certificado que puede utilizarse para enviar un certificado de cliente mediante la clase HttpWebRequest , utilice uno de los métodos siguientes:

Método 1

Utilice la clase X509Certificate para leer el certificado de un archivo .cer y, a continuación, establezca la propiedad ClientCertificates .

Método 2

Utilice CryptoAPI llamadas para obtener el certificado desde el almacén de certificados y, a continuación, establezca la clase X509Certificate en el certificado recibido en el almacén de certificados. A continuación, puede establecer la propiedad ClientCertificates .

Requisitos para enviar un certificado de cliente

Cuando trabaja con aplicaciones ASP.NET, asegúrese de que se completan los siguientes requisitos:
  • El certificado de cliente debe estar instalado en el subárbol de registro LOCAL_MACHINE y no en el subárbol del registro CURRENT_USER. Para confirmar que se ha instalado el certificado de cliente, siga estos pasos:
    1. Haga clic en Inicio , haga clic en Ejecutar , escriba mmc y, a continuación, haga clic en Aceptar .
    2. En el menú archivo , haga clic en Agregar o quitar complemento .
    3. En el cuadro de diálogo Agregar o quitar complemento , haga clic en Agregar .
    4. En el cuadro de diálogo Agregar complemento independiente , haga clic en certificados y, a continuación, haga clic en Agregar .
    5. En el cuadro de diálogo complemento certificados , haga clic en cuenta de equipo y, a continuación, haga clic en siguiente
    6. En el cuadro de diálogo Seleccionar equipo , haga clic en Finalizar .
    7. En el cuadro de diálogo Agregar complemento independiente , haga clic en Cerrar y, a continuación, haga clic en Aceptar .
    8. Expanda certificados (equipo local) , expanda personal y, a continuación, haga clic en certificados .
    En el panel derecho, debe aparecer el certificado de cliente.
  • El usuario de ASP.NET debe dar permisos de cuenta a la clave privada para el certificado de cliente. Para asignar permisos de cuenta a la clave privada para el certificado de cliente al usuario de ASP.NET, utilice la herramienta WinHttpCertCfg.exe.Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
    823193Cómo obtener las herramientas de certificado y seguimiento de Windows HTTP 5.1
    Para obtener más información acerca de cómo utilizar esta herramienta, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):
    Herramienta de configuración de certificados WinHttpCertCfg.exe, http://msdn2.microsoft.com/en-us/library/aa384088.aspx

Mediante un archivo .cer

Método 1 es más fácil de usar, pero el método requiere que tengan un archivo .cer. Si no tiene instalado el archivo .cer, utilice Microsoft Internet Explorer para exportar el archivo .cer.

El código siguiente describe cómo obtener un certificado desde un archivo .cer que puede utilizar con el class.
//Uncomment the following code if you need a proxy. The boolean true is used to bypass the local address.
//WebProxy proxyObject = new WebProxy("Your Proxy value",true); 
//GlobalProxySelection.Select = proxyObject;

// Obtain the certificate. 
try
{
	//You must change the path to point to your .cer file location. 
	X509Certificate Cert = X509Certificate.CreateFromCertFile("C:\\mycert.cer");
	// Handle any certificate errors on the certificate from the server.
	ServicePointManager.CertificatePolicy = new CertPolicy();
	// You must change the URL to point to your Web server.
	HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://YourServer/sample.asp");
	Request.ClientCertificates.Add(Cert);
	Request.UserAgent = "Client Cert Sample";
	Request.Method = "GET";
	HttpWebResponse Response = (HttpWebResponse)Request.GetResponse();
	// Print the repsonse headers.
	Console.WriteLine("{0}",Response.Headers);
	Console.WriteLine();
	// Get the certificate data.
	StreamReader sr = new StreamReader(Response.GetResponseStream(), Encoding.Default);
	int count;
	char [] ReadBuf = new char[1024];
	do
	{
		count = sr.Read(ReadBuf, 0, 1024);
		if (0 != count)
		{
			Console.WriteLine(new string(ReadBuf));
		}
						
	}while(count > 0);
}
catch(Exception e)
{
	Console.WriteLine(e.Message);
}
	

//Implement the ICertificatePolicy interface.
class CertPolicy: ICertificatePolicy
{
	public bool CheckValidationResult(ServicePoint srvPoint, 
X509Certificate certificate, WebRequest request, int certificateProblem)
	{
		// You can do your own certificate checking.
		// You can obtain the error values from WinError.h.

		// Return true so that any certificate will work with this sample.
		return true;
	}
}

Mediante llamadas a CryptoAPI

Si debe obtener el certificado del almacén de certificados, utilice las funciones de CryptoAPI para obtener el certificado y, después, almacenarlo en un objeto de la clase X509Certificate . La clase de X509CertificateCollection enumera todos los certificados en un almacén y, a continuación, los coloca en un objeto de clase X509CertificateCollection .

Si desea obtener un certificado específico, debe cambiar el código de clase para obtener un certificado específico mediante la función CertFindCertificateInStore . Esta función se declara en el archivo de WinCrypt.h. Como alternativa, puede enumerar la función X509CertificateCollection para buscar el certificado que desee.

El código de ejemplo siguiente utiliza el primer certificado de la colección que se devuelve desde la función CertEnumCertificatesInStore .
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;

namespace SelectClientCert
{
	/// Sample that describes how how to select client cetificate and send it to the server.

	class MyCerts{

		private static int CERT_STORE_PROV_SYSTEM = 10;
		private static int CERT_SYSTEM_STORE_CURRENT_USER = (1 << 16);
		///private static int CERT_SYSTEM_STORE_LOCAL_MACHINE = (2 << 16);

		[DllImport("CRYPT32", EntryPoint="CertOpenStore", CharSet=CharSet.Unicode, SetLastError=true)]
		public static extern IntPtr CertOpenStore(
			int storeProvider, int encodingType,
			int hcryptProv, int flags, string pvPara);

		[DllImport("CRYPT32", EntryPoint="CertEnumCertificatesInStore", CharSet=CharSet.Unicode, SetLastError=true)]
		public static extern IntPtr CertEnumCertificatesInStore(
			IntPtr storeProvider,
			IntPtr prevCertContext);

		[DllImport("CRYPT32", EntryPoint="CertCloseStore", CharSet=CharSet.Unicode, SetLastError=true)]
		public static extern bool CertCloseStore(
			IntPtr storeProvider,
			int flags);
		
		X509CertificateCollection m_certs;

		public MyCerts(){
			m_certs = new X509CertificateCollection();
		}

		public int Init()
		{
			IntPtr storeHandle;
			storeHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, "MY");
			IntPtr currentCertContext;
			currentCertContext = CertEnumCertificatesInStore(storeHandle, (IntPtr)0);
			int i = 0;
			while (currentCertContext != (IntPtr)0) 
			{
				m_certs.Insert(i++, new X509Certificate(currentCertContext));
				currentCertContext = CertEnumCertificatesInStore(storeHandle, currentCertContext);
			}
			CertCloseStore(storeHandle, 0);

			return m_certs.Count;
		}
		
		public X509Certificate this [int index]
		{
			get 
			{
				// Check the index limits.
				if (index < 0 || index > m_certs.Count)
					return null;
				else
					return m_certs[index];
			}
		}
	};
	class MyHttpResource
	{
		String m_url;

		public MyHttpResource(string url){
			m_url = url;
		}

		public void GetFile(){

			HttpWebResponse  result = null;

			try{
			
				HttpWebRequest req = (HttpWebRequest)WebRequest.Create(m_url);
				req.Credentials  = CredentialCache.DefaultCredentials;

				///Method1
				//req.ClientCertificates.Add(X509Certificate.CreateFromCertFile("D:\\Temp\\cert\\c1.cer"));
		
				///Method2
				///Uses interop services
				MyCerts mycert = new MyCerts();
				if(mycert.Init() > 0)
					req.ClientCertificates.Add(mycert[0]);

				result = (HttpWebResponse)req.GetResponse();
				
				Stream ReceiveStream = result.GetResponseStream();
				Encoding encode = System.Text.Encoding.GetEncoding("utf-8");

				StreamReader sr = new StreamReader( ReceiveStream, encode );
				Console.WriteLine("\r\nResponse stream received");

				Char[] read = new Char[256];
				int count = sr.Read( read, 0, 256 );

				Console.WriteLine("HTTP Response...\r\n");
				while (count > 0) 
				{
					String str = new String(read, 0, count);
					Console.Write(str);
					count = sr.Read(read, 0, 256);
				}

			} 
			catch(WebException e) 
			{
            
				Console.WriteLine("\r\nError:");
				#if (DEBUG)
					Console.WriteLine(e.ToString());
				#else		
					Console.WriteLine(e.Message); 				
				#endif

			} 
			finally 
			{
				if ( result != null ) {
					result.Close();
				}
			}
				
		}
	
	}

	class CertSample
	{
		static void Main(string[] args)
		{
			try
			{
				if (args.Length < 1)
				{
					Console.WriteLine("No url is entered to download, returning.\n");
					Console.WriteLine("Usage: CertSample <urltoget>\n");
					Console.WriteLine("  e.g: CertSample https://servername \n"); 

					return;
				}

				MyHttpResource hr = new MyHttpResource(args[0]);
				hr.GetFile();
			}
			catch(Exception e)
			{
				Console.WriteLine(e.ToString());
			}
			return;
		}
	}
}

Referencias

Para obtener más información, visite los siguientes sitios Web de Microsoft Developer Network (MSDN):
Clase X509Certificate
http://msdn2.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate(vs.71).aspx
Platform SDK: cifrado
http://msdn2.microsoft.com/en-us/library/aa380255.aspx

Propiedades

Id. de artículo: 895971 - Última revisión: viernes, 18 de mayo de 2007 - Versión: 1.6
La información de este artículo se refiere a:
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
Palabras clave: 
kbmt kbhowtomaster kbaspnet kbsample kbcode kbdigitalcertificates kbprogramming kbwebclasses kbhowto kbinfo KB895971 KbMtes
Traducción automática
IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.
Haga clic aquí para ver el artículo original (en inglés): 895971

Enviar comentarios

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com