Как отправить сертификат клиента с помощью классов HttpWebRequest и HttpWebResponse в Microsoft Visual C# .NET

Переводы статьи Переводы статьи
Код статьи: 895971 - Vizualiza?i produsele pentru care se aplic? acest articol.

Требования

Чтобы отправить сертификат клиента из приложений Microsoft ASP.NET необходимо иметь следующих исправлений или пакетов обновления:

Microsoft платформа.NET Framework 1.0

Платформа.NET Framework 1.0 Пакет обновления 3 (SP3), необходимо установить или необходимо установить исправление 817854. Для получения дополнительных сведений нажмите кнопку следующий номер статьи базы знаний Майкрософт:
817854ИСПРАВИТЬ: ASP.NET веб-приложение не может передать клиентский сертификат на защищенной веб-узел

Платформа.NET Framework 1.1

Платформа.NET Framework 1.1 Пакет обновления 1 (SP1), необходимо установить или необходимо установить исправление 831138. Для Дополнительные сведения, щелкните следующий номер статьи в Microsoft Knowledge Base:
831138ИСПРАВИТЬ: Приложения платформа.NET Framework, используя метод System.Net.WebRequest очень часто возникают ошибки OutOfMemoryException
Развернуть все | Свернуть все

В этой статье

ВВЕДЕНИЕ

В данной статье описывается отправить сертификат клиента с помощью классов HttpWebRequest и HttpWebResponse в Microsoft Visual C# NET.

Дополнительная информация

Клиент может отправить сертификат при веб-сервера необходимо с помощью HttpWebRequest и HttpWebResponse классы. Чтобы получить сертификат, который может использоваться для отправки сертификат клиента с помощью класса HttpWebRequest , воспользуйтесь одним из следующих методов:

Способ 1

Использовать класс X509Certificate для чтения сертификата из CER-файл, а затем задайте свойство ClientCertificates .

Способ 2

Использовать вызовы CryptoAPI для получения сертификата из сертификата хранения, а затем установите класса X509Certificate для сертификата, полученный из сертификата хранилище. Затем можно задать свойство ClientCertificates .

Требования для передачи сертификата клиента

При работе с приложениями ASP.NET, убедитесь, что следующие требования выполняются.
  • Сертификат клиента должен быть установлен в Куст реестра LOCAL_MACHINE, а не в функции CURRENT_USER куст реестра. Для Подтверждение установки сертификата клиента, выполните следующие действия:
    1. Нажмите кнопку Пуск, нажмите кнопку Запуск, тип MMC, а затем нажмите кнопку ОК.
    2. На Файл меню, нажмите кнопку Добавление и удаление оснастки.
    3. В Добавление и удаление оснастки диалоговое окно «» Нажмите кнопку Добавить.
    4. В Добавить изолированную оснастку диалоговое окно Выберите Сертификаты, а затем нажмите кнопку Добавить.
    5. В Оснастки сертификатов диалоговое окно Выберите Учетная запись компьютера, а затем нажмите кнопку Далее
    6. В Выбор компьютера диалоговое окно «» Нажмите кнопку "Готово".
    7. В Добавить изолированную оснастку диалоговое окно Выберите Закрыть, а затем нажмите кнопку ОК.
    8. Разверните узел Сертификаты (локальный компьютер), Разверните узел Личные, а затем нажмите кнопку Сертификаты.
    В правой панели щелкните сертификат клиента должен быть в списке.
  • Пользователь ASP.NET необходимо предоставить разрешения учетной записи закрытый ключ для сертификата клиента. Чтобы предоставить учетной записи пользователя ASP.NET использовать разрешения для закрытого ключа для сертификата клиента Средство WinHttpCertCfg.exe. Для получения дополнительных сведений сведения, щелкните следующий номер статьи в Microsoft Knowledge Base:
    823193Как получить сертификат и трассировки средства Windows HTTP 5.1
    Дополнительные сведения об использовании этого средства посетите следующий веб-узел Microsoft Developer Network (MSDN):
    WinHttpCertCfg.exe, средство настройки сертификата http://msdn2.Microsoft.com/en-us/library/aa384088.aspx

Использование CER-файл

1 Метод проще в использовании, но метод требует наличия файл .cer. Если у вас установлен CER-файл, с помощью Интернета Обозреватель для экспорта в файл .cer.

Описывает следующий исходный код как получить сертификат из CER-файл, который можно использовать в классе HttpWebRequest .
//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;
	}
}

С помощью вызовов CryptoAPI

Если необходимо получить сертификат из хранилища сертификатов, с помощью Чтобы получить сертификат и сохраните его в объект класса X509Certificate функции CryptoAPI. Класс X509CertificateCollection перечисляет все сертификаты в хранилище, а затем размещает их в объект класса X509CertificateCollection .

Если вы хотите получить определенный сертификат, необходимо изменить код класса для получения определенного сертификата с помощью функции CertFindCertificateInStore . Эта функция объявляется в файле Wincrypt.h. Кроме того можно перечислить функции X509CertificateCollection для поиска сертификата, который требуется.

В Следующий пример кода использует первый сертификат в коллекции возвращаемый функцией 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;
		}
	}
}

Ссылки

Для получения дополнительных сведений посетите следующий Developer Network (MSDN) веб-узлы:
Класс x509certificate
.aspx http://msdn2.Microsoft.com/en-us/library/System.Security.Cryptography.X509Certificates.x509certificate (vs.71)
Пакет SDK для платформы: криптография
http://msdn2.Microsoft.com/en-us/library/aa380255.aspx

Свойства

Код статьи: 895971 - Последний отзыв: 16 декабря 2012 г. - Revision: 6.0
Информация в данной статье относится к следующим продуктам.
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
Ключевые слова: 
kbhowtomaster kbaspnet kbsample kbcode kbdigitalcertificates kbprogramming kbwebclasses kbhowto kbinfo kbmt KB895971 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке: 895971

Отправить отзыв

 

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