Comment faire pour envoyer un certificat client en utilisant les classes HttpWebRequest et HttpWebResponse dans Visual C# .NET

Traductions disponibles Traductions disponibles
Numéro d'article: 895971 - Voir les produits auxquels s'applique cet article

Configuration requise

Pour envoyer un certificat client à partir d'applications ASP.NET, vous devez disposer des correctifs suivants les service packs installés :

Microsoft .NET framework 1.0

Vous devez installer .NET Framework 1.0 Service Pack 3 (SP3) ou vous devez installer le correctif 817854. Pour plus d'informations, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la Base de connaissances Microsoft :
817854 CORRECTIF : application Web ASP.NET ne peut pas fournir un certificat client à un site Web sécurisé

.NET framework 1.1

Vous devez installer le .NET Framework 1.1 Service Pack 1 (SP1) ou vous devez installer le correctif 831138. Pour plus d'informations, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la Base de connaissances Microsoft :
831138 CORRECTIF : une application .NET Framework qui utilise la méthode System.Net.WebRequest très fréquemment rencontre des erreurs d'exception OutOfMemoryException
Agrandir tout | Réduire tout

Sommaire

INTRODUCTION

Cet article explique comment envoyer un certificat client via les classes HttpWebRequest et HttpWebResponse dans Microsoft Visual C# .NET.

Plus d'informations

Vous pouvez envoyer un certificat client lorsque le serveur Web requiert un à l'aide la HttpWebRequest et les classes HttpWebResponse . Pour obtenir un certificat qui peut être utilisé pour envoyer un certificat client à l'aide de la classe HttpWebRequest , utilisez une des méthodes suivantes :

Méthode 1

Utiliser la classe X509Certificate à lire le certificat dans un fichier .cer, puis définir la propriété ClientCertificates .

Méthode 2

Utiliser des appels CryptoAPI pour obtenir le certificat à partir du magasin de certificats, puis définir la classe X509Certificate au certificat que vous avez reçu à partir du magasin de certificats. Vous pouvez ensuite définir la propriété ClientCertificates .

Configuration requise pour l'envoi d'un certificat client

Lorsque vous travaillez avec des applications ASP.NET, assurez-vous que les conditions suivantes sont terminées :
  • Le certificat client doit être installé dans la ruche de Registre LOCAL_MACHINE et non dans la ruche de Registre CURRENT_USER. Pour confirmer où le certificat client est installé, procédez comme suit :
    1. Cliquez sur Démarrer , cliquez sur Exécuter , tapez mmc et puis cliquez sur OK .
    2. Dans le menu Fichier , cliquez sur Ajouter/Supprimer un composant logiciel enfichable .
    3. Dans la boîte de dialogue Ajouter/Supprimer un composant logiciel enfichable , cliquez sur Ajouter .
    4. Dans la boîte de dialogue Ajout d'un composant logiciel enfichable autonome , cliquez sur certificats , puis cliquez sur Ajouter .
    5. Dans la boîte de dialogue composant logiciel enfichable Certificats , cliquez sur compte d'ordinateur , puis cliquez sur suivant
    6. Dans la boîte de dialogue Sélectionner un ordinateur , cliquez sur Terminer .
    7. Dans la boîte de dialogue Ajout d'un composant logiciel enfichable autonome , cliquez sur Fermer , puis cliquez sur OK .
    8. Développez Certificats (ordinateur local) , développez personnels et puis cliquez sur certificats .
    Le certificat client doit être répertorié dans le volet droit.
  • Vous devez donner les autorisations de compte à la clé privée pour le certificat client à l'utilisateur ASP.NET. Pour donner à l'utilisateur ASP.NET autorisations de compte à la clé privée pour le certificat client, utilisez l'outil WinHttpCertCfg.exe. Pour plus d'informations, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la Base de connaissances Microsoft :
    823193 Comment obtenir les outils de certificat et de trace Windows HTTP 5.1
    Pour plus d'informations utiliser cet outil, reportez-vous au site de Web MSDN (Microsoft Developer Network) suivant :
    WinHttpCertCfg.exe, une configuration de certificat outil http://msdn2.microsoft.com/en-us/library/aa384088.aspx

L'aide d'un fichier .cer

La méthode 1 est plus facile à utiliser, mais méthode nécessite que vous disposez d'un fichier .cer. Si vous n'avez pas le fichier .cer installé, utilisez Microsoft Internet Explorer pour exporter le fichier .cer.

Le code source suivant explique comment obtenir un certificat provenant d'un fichier .cer que vous pouvez utiliser avec la 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;
	}
}

L'aide d'appels CryptoAPI

Si vous devez obtenir le certificat à partir du magasin de certificats, utilisez les fonctions CryptoAPI pour obtenir le certificat et puis stockez-la dans un objet de classe X509Certificate . La classe X509CertificateCollection énumère tous les certificats dans un magasin et les place ensuite dans un objet de classe X509CertificateCollection .

Si vous souhaitez obtenir un certificat spécifique, vous devez modifier le code de classe pour obtenir un certificat spécifique à l'aide de la fonction CertFindCertificateInStore . Cette fonction est déclarée dans le fichier wincrypt.h. Sinon, vous pouvez énumérer la fonction X509CertificateCollection pour trouver le certificat souhaité.

Le code exemple suivant utilise le premier certificat dans la collection qui est renvoyée à partir de la fonction 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;
		}
	}
}

Références

Pour plus d'informations, reportez-vous aux sites Microsoft Developer réseau MSDN (Web adresses suivantes :
Classe X509Certificate
http://msdn2.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate(vs.71).aspx
Plate-forme SDK : chiffrement
http://msdn2.microsoft.com/en-us/library/aa380255.aspx

Propriétés

Numéro d'article: 895971 - Dernière mise à jour: vendredi 18 mai 2007 - Version: 1.6
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
Mots-clés : 
kbmt kbhowtomaster kbaspnet kbsample kbcode kbdigitalcertificates kbprogramming kbwebclasses kbhowto kbinfo KB895971 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 895971
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

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