如何以程式設計的方式安裝網際網路資訊伺服器 (IIS) 的 SSL 憑證

重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。

按一下這裡查看此文章的英文版本:313624
本文已封存。本文係以「現狀」提供且不會再更新。
重要本文包含有關編輯中繼庫的資訊。 編輯中繼庫之前請確認您有問題發生時,可以還原的備份複本。有關如何執行這項作業,請參閱 」 設定備份/還原 > 說明主題中 Microsoft 管理主控台 (MMC)]。
結論

本文將逐步說明如何以程式設計方式建立,並再安裝安全通訊端層 (SSL) 憑證網際網路資訊伺服器 (IIS)。雖然 IIS 4.0 版和 IIS 版本 5.0 每個提供使用者介面 (UI),以建立並再安裝 SSL 伺服器憑證,您可以也完成工作以程式設計的方式。

back to the top

建立的步驟,然後安裝 SSL 憑證 (英文)

若要以程式設計方式建立並再安裝 IIS 伺服器的 SSL 憑證依照下列步驟執行:
  1. 您必須將要求傳送至憑證授權單位來發行伺服器憑證。如果您已經有該憑證而然後您將其儲存在 IIS 伺服器上檔案,並不會傳送要求。
  2. 將憑證匯入適當的憑證存放區。
  3. 將 IIS 設定為使用步驟 1 取得的憑證。

back to the top

設定 IIS 建立,並再安裝 SSL 憑證

警告如果您不正確地編輯中繼庫可能會導致嚴重的問題,甚至必須重新安裝任何使用中繼庫的產品。 Microsoft 無法保證可以獲得解決的問題,因此,如果您不正確地編輯中繼庫產生。編輯中繼庫,請自行負擔相關的風險。

附註永遠中繼庫之前先備份您編輯它。 請依照下列步驟來設定 IIS 以建立並再安裝 SSL 憑證:
  1. 使用 Microsoft Windows 加密 API 來取得 指紋 的憑證屬性。
  2. 您必須設定 IIS Metabase 屬性 SSLCertHash憑證碼 的值。
  3. 您必須設定 IIS Metabase 屬性 SSLStoreName,至您想要使用存放區。
請參閱下列文章小節,以取得之憑證的 指模 的程式碼範例,然後取得 SSLCertHash 屬性:
C Code to Obtain the Thumbprint of a Server Authentication Certificate
C Code to Enter the SSLCertHash Property into the Metabase

back to the top

在特定的網站上啟用 SSL 的步驟

您執行 < 設定 IIS 以建立和次要來安裝 SSL 憑證 > 一節中的步驟之後您就可以啟用 SSL 上特定網站或特定資料夾中。若要如何讓您必須啟用 SSL 選項在您想要使用的資料夾中。下列步驟執行對應的 < 設定 IIS 以建立和次要來安裝 SSL 憑證 > 一節中所述的每個步驟:
  1. 當您呼叫 CEnroll::createPKCS10() 方法時,會建立憑證要求。設定為下列的預先定義值的使用方式: szOID_PKIX_KP_SERVER_AUTH
    #define szOID_PKIX_KP_SERVER_AUTH       "1.3.6.1.5.5.7.3.1"		
  2. 當您呼叫 ICertRequest::Submit () 方法時,憑證要求提交到憑證授權單位。
  3. 從該憑證授權單位,擷取憑證以及然後在適當的存放區中安裝它。IIS 伺服器憑證精靈 」 尋找只可用於在本機電腦憑證存放區伺服器驗證的憑證。


back to the top

若要設定 IIS 的步驟

將憑證儲存到儲存區之後您必須設定 IIS,如下所示:
  1. 使用 CertGetCertificateContextProperty() 方法來取得 憑證碼 屬性和 CERT_HASH_PROP_ID 屬性的值。CertGetCertificateContextProperty() 函式會使用 CryptHashCertificate() 方法來計算 CERT_HASH_PROP_ID 屬性的值。如果不存在的雜湊值,CertGetCertificateContextProperty() 傳回 SHA1 演算法。
  2. 您必須建立一個新二進位 Metabase 屬性,SSLCertHash,對應到 Web 站台。憑證 指紋 取得這一節的步驟 1 中的設定 SSLCertHash。這個問題時結構描述不正確地指定 SSLCertHash 屬性為已展開的 null 已經終止字串,而不是為二進位資料,然後再您不能使用 IIS 管理物件匯入 SSLCertHash。您可以使用只有 IIS Admin 基底物件匯入這個值。若要使用 IIS 管理基底物件 SSLCertHash,您必須使用 Decimal 值 5506。
  3. 您必須建立新字串的 Metabase 屬性,SSLStoreName,對應的 Web 站台。將字串值,SSLStoreName。您可能可以設定 SSLStoreName 透過 (比方說在 ADSI 指令碼) 的 [IIS 管理物件或透過 IIS 管理基底物件。若要使用 IIS 管理基底物件 SSLStoreName,使用 Decimal 值 5511。


back to the top

C 的程式碼,以取得伺服器驗證憑證指紋

下列範例 Microsoft C 程式碼將告訴您,如何取得的伺服器驗證憑證 指紋 屬性:
#include <stdio.h>#include <windows.h>#include <wincrypt.h>#define MY_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)//--------------------------------------------------------------------//    Define the name of the store where the needed certificate//    can be found. #define CERT_STORE_NAME  L"MY"//--------------------------------------------------------------------//   Declare local functions.//   Local function definitions follow main.void HandleError(char *s);void main(void){//--------------------------------------------------------------------// Declare and initialize local variables. // This includes initializing a pointer to the message. // Usually, the message will exist somewhere and a pointer will// be passed to the application.//--------------------------------------------------------------------// System store handleHCERTSTORE hStoreHandle;   //--------------------------------------------------------------------// Pointer to a certificatePCCERT_CONTEXT pCert;PCCERT_CONTEXT pPrevCert; LPBYTE pEncodedBytes = NULL;LPBYTE pHash;DWORD cbData, i;//--------------------------------------------------------------------// Open a certificate store.if ( !( hStoreHandle = CertOpenStore(   CERT_STORE_PROV_SYSTEM,   0,   NULL,   CERT_SYSTEM_STORE_LOCAL_MACHINE,   CERT_STORE_NAME))){     HandleError("The MY store could not be opened.");}pPrevCert = NULL;for (; ((pCert = CertEnumCertificatesInStore(hStoreHandle, pPrevCert)) 	                                         != NULL);    pPrevCert = pCert){    CERT_ENHKEY_USAGE *pKeyUsage;    DWORD j, nLen;    BOOL bFound = FALSE;    char certName[1024];    nLen = sizeof(certName);    certName[0] = 0;    if (CertNameToStr(MY_TYPE, &(pCert->pCertInfo->Subject),        CERT_X500_NAME_STR,        certName,        sizeof(certName)))    {        printf("Checking %s certificate\n", certName);    }    cbData = 0;    if (!CertGetEnhancedKeyUsage(pCert,        0,        NULL,        &cbData) || cbData == 0)    {        if (GetLastError() == CRYPT_E_NOT_FOUND)        {            printf("%s certificate is for all key usages\n", certName);            break;        }        else            printf("CertGetEnhancedKeyUsage failed with error code : %08X\n",                GetLastError());    }    pKeyUsage = (CERT_ENHKEY_USAGE *)        HeapAlloc(GetProcessHeap(), 0, cbData);    if (pKeyUsage == NULL)    {        printf("HeapAlloc failed with error code : %08X\n",            GetLastError());        HandleError("Certificate not found.");    }    if (!CertGetEnhancedKeyUsage(pCert,        0,        pKeyUsage,        &cbData))    {        if (GetLastError() == CRYPT_E_NOT_FOUND)        {            printf("%s certificate is for all key usages\n", certName);            HeapFree(GetProcessHeap(), 0, pKeyUsage);            break;        }        else        {            printf("CertGetEnhancedKeyUsage failed with error code : %08X\n",                GetLastError());            HeapFree(GetProcessHeap(), 0, pKeyUsage);            continue;        }    }    if (pKeyUsage->cUsageIdentifier == 0)    {        printf("%s certificate is for all key usages\n", certName);        HeapFree(GetProcessHeap(), 0, pKeyUsage);        break;    }    bFound = FALSE;    for (j = 0; j < pKeyUsage->cUsageIdentifier; j++)    {        if (strcmpi(pKeyUsage->rgpszUsageIdentifier[j], 			        szOID_PKIX_KP_SERVER_AUTH) == 0)        {            printf("%s certificate is for Server Authentication\n", 				   certName);            bFound = TRUE;            break;        }    }    HeapFree(GetProcessHeap(), 0, pKeyUsage);    if (bFound)        break;}if (pCert == NULL)   HandleError("Certificate not found.");if (pPrevCert){    CertFreeCertificateContext(pPrevCert);    pPrevCert = NULL;}/// CASE 2 Get the hash from the certificatepHash = NULL;cbData = 0;CertGetCertificateContextProperty(pCert, CERT_HASH_PROP_ID, NULL, &cbData);if (cbData == 0){   HandleError("CertGetCertificateContextProperty 1 failed");}pHash = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, cbData);if (pHash == NULL){   HandleError("HeapAlloc failed");}if (!CertGetCertificateContextProperty(pCert, CERT_HASH_PROP_ID, pHash, 	                                   &cbData)){   HandleError("CertGetCertificateContextProperty 2 failed");}printf("CERT_HASH_PROP_ID Length is %d\n", cbData);printf("CERT_HASH_PROP_ID BYTES [", cbData);for (i = 0; i < cbData; i++){    printf("%02X", pHash[i]);}printf("]\n");//--------------------------------------------------------------------// Clean up and free memory.if (pEncodedBytes)    HeapFree(GetProcessHeap(), 0, pEncodedBytes);if (pHash)    HeapFree(GetProcessHeap(), 0, pHash);if(pCert)     CertFreeCertificateContext(pCert);if(CertCloseStore(      hStoreHandle,       CERT_CLOSE_STORE_CHECK_FLAG)){    printf("The store closed and all certificates are freed. \n");}else{    printf("Store closed -- \n"          "not all certificates, CRLs or CTLs were freed");}} // End of main//--------------------------------------------------------------------//  This example uses the function HandleError, a simple error//  handling function, to print an error message to the standard error //  (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting.void HandleError(char *s){    fprintf(stderr,"An error occurred in running the program. \n");    fprintf(stderr,"%s\n",s);    fprintf(stderr, "Error number %x.\n", GetLastError());    fprintf(stderr, "Program terminating. \n");    exit(1);} // End of HandleError


back to the top

C Metabase 中輸入 SSLCertHash 屬性的程式碼

下列範例程式碼說明如何使用 IIS 管理基底物件在 Metabase 中設定 SSLCertHash 方法。下列程式碼會使用任意的二進位陣列為憑證 指紋。實際的程式碼會使用 指紋 值,取得當"取得 [指紋的有伺服器驗證憑證 > 一節中執行程式碼。視您如何定義 SetData 方法一起編譯時期,您可以設定 SSLCertHash,或如果您已經為網站設定 SSL,可以取得 SSLCertHash 存在。 The SSLCertHash method return the existing CertHash:
#define UNICODE // unicode must be defined for Metabase access#define INITGUID #include <windows.h>#include <httpfilt.h>#include <stdio.h> #define SETDATA#include <iadmw.h>    // COM Interface header #include <iiscnfg.h>  // MD_ & IIS_MD_ #defines extern "C" wmain (int argc, TCHAR ** argv){  	IMSAdminBase  *pIMeta;  	METADATA_HANDLE MyHandle;     HRESULT hres;   	METADATA_RECORD record = {0};    TCHAR szError [2048];	BYTE *myData=NULL;    DWORD dwSize = sizeof (record); 	DWORD i;	// this just a sample of some thumbprint	BYTE bar[]={0x24, 0xC6, 0xBA, 0xBB, 0x81, 0x76, 0x05, 0xC9, 0xC3, 		        0x97, 0x6D, 0x4D, 0xEB, 0x85, 0x8F, 0x4F, 0xBF, 0x38,				0xFD};            CoInitialize (NULL);        // get a pointer to the IIS Admin Base Object	hres = CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL, 			IID_IMSAdminBase, (void **) &pIMeta);  	if (FAILED(hres))  	{	    wsprintf (szError, L"CoCreateInstance Failed. Error: %x\n", hres);        printf ("%S\n", szError);		CoUninitialize();        return TRUE;  	}        // for this test use only 1st server instance    hres = pIMeta->OpenKey(METADATA_MASTER_ROOT_HANDLE, L"/LM", 		METADATA_PERMISSION_READ|METADATA_PERMISSION_WRITE, 20, &MyHandle); 	if (FAILED (hres) )	{		wsprintf (szError, L"OpenKey Failed. Error: %x\n", hres);        printf ("%S\n", szError);		goto clean;	}    	// SSLCertHash = 5506	record.dwMDIdentifier =  5506;    record.dwMDAttributes =METADATA_INHERIT;    record.dwMDUserType=IIS_MD_UT_SERVER;    record.dwMDDataType= BINARY_METADATA;    record.pbMDData = (unsigned char *) myData;#ifndef SETDATA#pragma message ("Building for GetData\n")    	again:    hres = pIMeta->GetData (MyHandle,argv[1], &record, &dwSize);   	if (FAILED (hres) )	{		if (hres == MD_ERROR_DATA_NOT_FOUND)		{			printf ("%S\n", L"Data not found, no certificate is set!");			goto clean;		}		else if (HRESULT_CODE(hres)==ERROR_INSUFFICIENT_BUFFER)		{			record.dwMDDataLen=dwSize;			myData = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, dwSize);			record.pbMDData  = (unsigned char *)myData;		    goto again;		}		else  		{			wsprintf (szError, L"GetData Failed. Error: %x\n", hres);			printf ("%S\n", szError);			goto clean;;		}	}	printf ("%S", L"Got thumbprint. You can compare" 		          L" it with the MMC for IIS value:\n");		for ( i=0; i<(record.dwMDDataLen/sizeof (BYTE)); i++)				printf ("%2X ", myData[i]);  	HeapFree(GetProcessHeap(), 0, myData);#else#pragma message ("Building for SetData\n")		record.pbMDData = bar;	record.dwMDDataLen = 19; // in real code it should be the size                                                    // of the thumbprint buffer	hres = pIMeta->SetData (MyHandle,argv[1], &record);	if (FAILED (hres) )	{		printf ("Set data failed: 0x%x!\n", hres);		goto clean;	}	else		printf ("New thumbprint is set\n");#endifclean:	pIMeta->CloseKey(MyHandle); 	pIMeta->SaveData();	pIMeta->Release();	CoUninitialize();	return 1;}


back to the top
参考
如需詳細資訊,請按一下下列的文件編號,檢視 「 Microsoft 知識庫 」 中的文件:
315588如何保障 ASP.NET 應用程式使用用戶端憑證的安全

back to the top

警告:本文為自動翻譯

內容

文章識別碼:313624 - 最後檢閱時間:12/07/2015 08:14:57 - 修訂: 2.2

Microsoft Internet Information Server 4.0, Microsoft Internet Information Services 5.0

  • kbnosurvey kbarchive kbmt kbcrypt kbapi kbhowtomaster kbsecurity kbisapiext kbhowto KB313624 KbMtzh
意見反應