Como enviar um certificado de cliente utilizando as classes HttpWebRequest e HttpWebResponse no Microsoft Visual C# .NET

Traduções de Artigos Traduções de Artigos
Artigo: 895971 - Ver produtos para os quais este artigo se aplica.

Requisitos

Para enviar um certificado de cliente de aplicações do Microsoft ASP.NET, tem de ter as seguintes correcções ou service packs instalados:

Microsoft .NET framework 1.0

Tem de instalar o .NET Framework 1.0 Service Pack 3 (SP3) ou, terá de instalar a correcção 817854.Para obter mais informações, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
817854CORRECÇÃO: Uma aplicação Web do ASP.NET não consegue entregar um certificado de cliente a um Web site com segurança melhorada

.NET framework 1.1

Tem de instalar o .NET Framework 1.1 Service Pack 1 (SP1) ou, terá de instalar a correcção 831138.Para obter mais informações, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
831138CORRECÇÃO: Uma aplicação do .NET Framework que utiliza o método System.Net.WebRequest muito frequentemente experiências OutOfMemoryException erros
Expandir tudo | Reduzir tudo

Nesta página

INTRODUÇÃO

Este artigo explica como enviar um certificado de cliente utilizando as classes HttpWebRequest e HttpWebResponse no Visual C# NET da Microsoft.

Mais Informação

Pode enviar um certificado de cliente quando o servidor Web requer um utilizando HttpWebRequest e as classes de HttpWebResponse . Para obter um certificado que pode ser utilizado para enviar um certificado de cliente utilizando a classe HttpWebRequest , utilize um dos seguintes métodos:

Método 1

Utilizar a classe de certificado x 509 para ler o certificado de um ficheiro .cer e, em seguida, defina a propriedade ClientCertificates .

Método 2

Utilize o CryptoAPI chamadas para obter o certificado do arquivo de certificados e defina a classe de certificado x 509 ao certificado que recebeu do arquivo de certificados. Em seguida, pode definir a propriedade ClientCertificates .

Requisitos para enviar um certificado de cliente

Quando trabalhar com aplicações ASP.NET, certifique-se que os seguintes requisitos foram concluídos:
  • O certificado de cliente tem de estar instalado no ramo de registo LOCAL_MACHINE e não no ramo de registo CURRENT_USER. Para confirmar onde está instalado o certificado de cliente, siga estes passos:
    1. Clique em Iniciar , clique em Executar , escreva mmc e, em seguida, clique em OK .
    2. No menu ficheiro , clique em Adicionar/remover Snap-in .
    3. Na caixa de diálogo Adicionar/remover Snap-in , clique em Adicionar .
    4. Na caixa de diálogo Adicionar Snap-in autónomo , clique em certificados e, em seguida, clique em Adicionar .
    5. Na caixa de diálogo snap-in Certificados , clique em conta de computador e, em seguida, clique em seguinte
    6. Na caixa de diálogo Seleccionar computador , clique em Concluir .
    7. Na caixa de diálogo Adicionar Snap-in autónomo , clique em Fechar e, em seguida, clique em OK .
    8. Expanda certificados (computador local) , expanda pessoal e, em seguida, clique em certificados .
    No painel da direita, deverá estar listado o certificado de cliente.
  • Tem de dar permissões de conta para a chave privada para o certificado de cliente o utilizador ASP.NET. Para atribuir o utilizador ASP.NET permissões de conta para a chave privada para o certificado de cliente, utilize a ferramenta WinHttpCertCfg.exe.Para obter mais informações, clique no número de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
    823193Como obter ferramentas de certificado e rastreio Windows HTTP 5.1
    Para obter mais informações sobre como utilizar esta ferramenta, visite o seguinte Web site da Microsoft Developer Network (MSDN):
    WinHttpCertCfg.exe, uma configuração de certificado ferramenta http://msdn2.microsoft.com/en-us/library/aa384088.aspx

Utilizando um ficheiro .cer

Método 1 é mais fácil de utilizar, mas o método requer que tenha um ficheiro .cer. Se não tiver o ficheiro .cer instalado, utilize Microsoft Internet Explorer para exportar o ficheiro .cer.

O código de origem que se segue descreve como obter um certificado de um ficheiro .cer que pode utilizar com 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;
	}
}

Utilizar chamadas de CryptoAPI

Se deve obter o certificado do arquivo de certificados, utilizar as funções da CryptoAPI para obter o certificado e, em seguida, guarde-o num objecto de classe de certificado x 509 . Classe X509CertificateCollection enumera todos os certificados num arquivo e, em seguida, coloca-os num objecto classe X509CertificateCollection .

Se pretender obter um certificado específico, tem de alterar o código de classe para obter um certificado específico utilizando a função CertFindCertificateInStore . Esta função está declarada no ficheiro Wincrypt.h. Em alternativa, pode enumerar a função X509CertificateCollection para localizar o certificado que pretende.

O código de exemplo seguinte utiliza o primeiro certificado na colecção é devolvida da função 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;
		}
	}
}

Referências

Para obter mais informações, visite os seguintes Web sites da Microsoft Developer Network (MSDN):
Classe de certificado x 509
http://msdn2.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate(vs.71).aspx
O Platform SDK: criptografia
http://msdn2.microsoft.com/en-us/library/aa380255.aspx

Propriedades

Artigo: 895971 - Última revisão: 18 de maio de 2007 - Revisão: 1.6
A informação contida neste artigo aplica-se a:
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
Palavras-chave: 
kbmt kbhowtomaster kbaspnet kbsample kbcode kbdigitalcertificates kbprogramming kbwebclasses kbhowto kbinfo KB895971 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 895971

Submeter comentários

 

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