Microsoft Visual C# .NET의 HttpWebRequest 및 HttpWebResponse 클래스를 사용하여 클라이언트 인증서를 보내는 방법

기술 자료 번역 기술 자료 번역
기술 자료: 895971 - 이 문서가 적용되는 제품 보기.

요구 사항

Microsoft ASP.NET 응용 프로그램에서 클라이언트 인증서를 보내려면 다음 핫픽스나 서비스 팩이 설치되어 있어야 합니다.

Microsoft .NET Framework 1.0

.NET Framework 1.0 서비스 팩 3(SP3)을 설치하거나 핫픽스 817854를 설치해야 합니다. 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
817854 FIX: ASP.NET 웹 응용 프로그램은 보안 웹 사이트로 클라이언트 인증서를 전달할 수 없다

.NET Framework 1.1

.NET Framework 1.1 서비스 팩 1(SP1)을 설치하거나 핫픽스 831138을 설치해야 합니다. 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
831138 FIX: System.Net.WebRequest 메서드를 사용하는 .NET Framework 응용 프로그램에서 OutOfMemoryException 오류가 매우 자주 발생한다
모두 확대 | 모두 축소

이 페이지에서

소개

이 문서에서는 Microsoft Visual C# NET의 HttpWebRequestHttpWebResponse 클래스를 사용하여 클라이언트 인증서를 보내는 방법을 설명합니다.

추가 정보

웹 서버가 요청할 경우 HttpWebRequestHttpWebResponse 클래스를 사용하여 클라이언트 인증서를 보낼 수 있습니다. HttpWebRequest 클래스를 사용하여 클라이언트 인증서를 보내는 데 사용할 수 있는 인증서를 얻으려면 다음 방법 중 하나를 사용하십시오.

방법 1

X509Certificate 클래스를 사용하여 .cer 파일에서 인증서를 읽은 다음 ClientCertificates 속성을 설정합니다.

방법 2

CryptoAPI 호출을 사용하여 인증서 저장소에서 인증서를 얻은 다음 이 인증서에 X509Certificate 클래스를 설정합니다. 그런 다음 ClientCertificates 속성을 설정합니다.

클라이언트 인증서 보내기 요구 사항

ASP.NET 응용 프로그램으로 작업하는 경우에는 다음 요구 사항이 충족되어야 합니다.
  • 클라이언트 인증서가 CURRENT_USER 레지스트리 하이브가 아니라 LOCAL_MACHINE 레지스트리 하이브에 설치되어 있어야 합니다. 클라이언트 인증서가 설치된 위치를 확인하려면 다음과 같이 하십시오.
    1. 시작, 실행을 차례로 누르고 mmc를 입력한 다음 확인을 누릅니다.
    2. 파일 메뉴에서 스냅인 추가/제거를 누릅니다.
    3. 스냅인 추가/제거 대화 상자에서 추가를 누릅니다.
    4. 독립 실행형 스냅인 추가 대화 상자에서 인증서를 누른 다음 추가를 누릅니다.
    5. 인증서 스냅인 대화 상자에서 컴퓨터 계정을 누르고 다음을 누릅니다.
    6. 컴퓨터 선택 대화 상자에서 마침을 누릅니다.
    7. 독립 실행형 스냅인 추가 대화 상자에서 닫기를 누른 다음 확인을 누릅니다.
    8. 인증서(로컬 컴퓨터), 개인을 차례로 확장하고 인증서를 누릅니다.
    오른쪽 창에 클라이언트 인증서가 표시됩니다.
  • 클라이언트 인증서의 개인 키에 ASP.NET 사용자 계정 권한을 부여해야 합니다. 클라이언트 인증서의 개인 키에 ASP.NET 사용자 계정 권한을 부여하려면 WinHttpCertCfg.exe 도구를 사용합니다. 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
    823193 INFO: Windows HTTP 5.1 인증서 및 추적 도구를 얻는 방법
    이 도구를 사용하는 방법에 대한 자세한 내용은 다음 MSDN(Microsoft Developer Network) 웹 사이트를 참조하십시오.
    WinHttpCertCfg.exe 인증서 구성 도구 http://msdn2.microsoft.com/en-us/library/aa384088.aspx(영문)

.cer 파일 사용

방법 1은 가장 쉬운 방법이지만 .cer 파일이 필요합니다. .cer 파일이 설치되어 있지 않은 경우에는 Microsoft Internet Explorer를 사용하여 .cer 파일을 내보낼 수 있습니다.

다음은 HttpWebRequest 클래스와 함께 사용할 수 있는 인증서를 .cer 파일에서 얻는 방법을 보여 주는 소스 코드입니다.
//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 호출 사용

인증서 저장소에서 인증서를 얻어야 하는 경우 CryptoAPI 함수를 사용하여 인증서를 얻은 다음 X509Certificate 클래스 개체에 저장합니다. 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;
		}
	}
}

참조

자세한 내용은 다음 MSDN(Microsoft Developer Network) 웹 사이트를 참조하십시오.
X509Certificate 클래스
http://msdn.microsoft.com/library/kor/default.asp?url=/library/kor/cpref/html/frlrfsystemsecuritycryptographyx509certificatesx509certificateclasstopic.asp
Platform SDK: 암호화
http://msdn2.microsoft.com/en-us/library/aa380255.aspx(영문)




Microsoft 제품 관련 기술 전문가들과 온라인으로 정보를 교환하시려면 Microsoft 뉴스 그룹에 참여하시기 바랍니다.

속성

기술 자료: 895971 - 마지막 검토: 2007년 1월 16일 화요일 - 수정: 1.4
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
키워드:?
kbhowto kbhowtomaster kbinfo kbprogramming kbwebclasses kbsample kbcode kbaspnet kbdigitalcertificates KB895971

피드백 보내기

 

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