現在オフラインです。再接続するためにインターネットの接続を待っています

Microsoft Visual C# .NET で HttpWebRequest および HttpWebResponse の各クラスを使用してクライアント証明書を送付する方法

はじめに
この資料では、Microsoft Visual C# .NET で、HttpWebRequest および HttpWebResponse の各クラスを使用してクライアント証明書を送付する方法について説明します。

必要条件

Microsoft ASP.NET アプリケーションからクライアント証明書を送付するには、次の修正プログラムまたは Service Pack がインストールされている必要があります。

Microsoft .NET Framework 1.0

.NET Framework 1.0 Service Pack 3 (SP3) または 817854 修正プログラムをインストールする必要があります。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
817854 [FIX] ASP.NET Web アプリケーションで、クライアント証明書をセキュリティで保護された Web サイトに送信できない

.NET Framework 1.1

.NET Framework 1.1 Service Pack 1 (SP1) または 831138 修正プログラムをインストールする必要があります。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
831138 [FIX] System.Net.WebRequest メソッドを使用する .NET Framework アプリケーションで頻繁に OutOfMemoryException エラーが発生する
詳細
Web サーバーでクライアント証明書が必要な場合は、HttpWebRequest および HttpWebResponse の各クラスを使用してクライアント証明書を送付できます。クライアント証明書の送付に使用される証明書を HttpWebRequest クラスを使用して取得するには、次のいずれかの手順を実行します。

方法 1

X509Certificate クラスを使用して .cer ファイルから証明書を読み取り、ClientCertificates プロパティを設定します。

方法 2

CryptoAPI 呼び出しを使用して証明書ストアから証明書を取得し、証明書ストアから受け取った証明書に対して X509Certificate クラスを設定します。次に ClientCertificates プロパティを設定します。

クライアント証明書の送付に必要な条件

ASP.NET アプリケーションを使用するときは、次の条件がすべて満たされている必要があります。
  • クライアント証明書は、CURRENT_USER レジストリ ハイブではなく、LOCAL_MACHINE レジストリ ハイブにインストールする必要があります。クライアント証明書がインストールされている場所を確認するには、次の手順を実行します。
    1. [スタート] ボタンをクリックし、[ファイル名を指定して実行] をクリックします。mmc と入力し、[OK] をクリックします。
    2. [ファイル] メニューの [スナップインの追加と削除] をクリックします。
    3. [スナップインの追加と削除] ダイアログ ボックスで [追加] をクリックします。
    4. [スタンドアロン スナップインの追加] ダイアログ ボックスの [証明書] をクリックし、[追加] をクリックします。
    5. [証明書スナップイン] ダイアログ ボックスの [コンピュータ アカウント] をクリックし、[次へ] をクリックします。
    6. [コンピュータの選択] ダイアログ ボックスで [完了] をクリックします。
    7. [スタンドアロン スナップインの追加] ダイアログ ボックスの [閉じる] をクリックし、[OK] をクリックします。
    8. [証明書 (ローカル コンピュータ)]、[個人] を順に展開し、次に [証明書] をクリックします。
    右側のペインに、クライアント証明書が一覧表示されます。
  • ASP.NET ユーザー アカウントには、クライアント証明書の秘密キーに対するアクセス許可を与える必要があります。ASP.NET ユーザー アカウントにクライアント証明書の秘密キーに対するアクセス許可を与えるには、WinHttpCertCfg.exe ツールを使用します。 関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
    823193 Windows HTTP 5.1 証明書とトレース ツールの入手方法
    このツールの使用方法の詳細については、以下の MSDN (Microsoft Developer Network) Web サイトを参照してください。
    WinHttpCertCfg.exe, a Certificate Configuration Tool
    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) Web サイトを参照してください。
プロパティ

文書番号:895971 - 最終更新日: 01/16/2007 08:22:00 - リビジョン: 1.4

  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework 1.0
  • kbhowto kbhowtomaster kbinfo kbprogramming kbwebclasses kbsample kbcode kbaspnet kbdigitalcertificates KB895971
フィードバック