Как программно установить SSL-сертификатов Internet Information Server (IIS)

Переводы статьи Переводы статьи
Код статьи: 313624 - Vizualiza?i produsele pentru care se aplic? acest articol.
Развернуть все | Свернуть все

В этой статье

Важно Данная статья содержит сведения об изменении метабазы. Перед изменением метабазы убедитесь, что резервную копию, которую можно восстановить, если возникает проблема. Сведения о том, как это сделать обратитесь к разделу справки "архивирование и восстановление конфигурации" консоли управления (MMC).

Аннотация


В этой статье описывается, как программно создать и затем установить Secure Sockets Layer (SSL) сертификатов Internet Information Server (IIS). На сервере IIS 4.0 и IIS 5.0 каждая версия предоставляет пользовательский интерфейс (UI) для создания, а затем установить сертификат сервера SSL, можно также выполнить задачу программным способом.



Шаги, чтобы создать и установить SSL-сертификатов

Для программного создания и затем установить сертификаты SSL для сервера IIS, выполните следующие действия:
  1. Toissue центр сертификации сертификат сервера должен отправить запрос. Если уже имеется сертификат, а затем можно сохранить в файле на сервере IIS, не отправлять запрос.
  2. Импортируйте сертификат в соответствующую certificatestore.
  3. Настройте службы IIS для использования сертификата, полученный instep 1.



Настроить службы IIS, чтобы создать и установить SSL сертификаты

Предупреждение Некорректное изменение метабазы может привести к серьезным проблемам, которые могут потребовать переустановки программ, использующих метабазу. Корпорация Майкрософт не гарантирует, что проблемы из-за неправильного изменения метабазы, могут быть устранены. Производите изменения метабазы на ваш собственный риск.

Примечание Всегда создавайте резервную копию метабазы перед изменением. Выполните следующие действия, чтобы настроить службы IIS, чтобы создать и установить SSL сертификатов:
  1. Используйте API-интерфейсов шифрования Microsoft Windows для получения свойств отпечатоксертификата.
  2. Свойство метабазы IIS SSLCertHashдолжно быть присвоено значение отпечатка.
  3. Необходимо задать свойство метабазы IIS SSLStoreNameв магазине, который вы хотите использовать.
В следующих разделах статьи образцы кода получить отпечаток сертификата, а затем свойство SSLCertHash obtainthe:
Код на языке C для получения отпечаток сертификата проверки подлинности сервера
Введите свойство SSLCertHash в метабазу кода на языке C



Действия для включения 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) , thecertification центр отправляется запрос на сертификат.
  3. Получить сертификат от certificationauthority, а затем установлена в соответствующее хранилище. Мастер сертификатсервера IIS проверяет только для сертификатов, его можно использовать для проверки подлинности сервера, в хранилище сертификатов локального компьютера.




Действия для настройки IIS

После сохранения сертификата в хранилище, необходимо настроить IIS следующим образом:
  1. Используйте метод CertGetCertificateContextProperty()для получения значения свойства Thumbprint и CERT_HASH_PROP_ID . Функция CertGetCertificateContextProperty() использует метод CryptHashCertificate() для вычисления значения свойства CERT_HASH_PROP_ID . Если хэш-значение не существует, то CertGetCertificateContextProperty() возвращает алгоритма SHA1 .
  2. Необходимо создать новые двоичные свойства метабазы, SSLCertHash, который соответствует веб-узлу. Значение SSLCertHash сертификат Thumbprint , полученным на шаге 1 этого раздела. При возникновении этой проблемы, theschema неправильно указывает propertyas SSLCertHash развернутой строку, оканчивающуюся нулем, а не как двоичные данные, а затем объектов IIS Admin нельзя использовать для импорта SSLCertHash. Это значение можно использовать только импорт IIS Admin Base objectsto. Чтобы использовать SSLCertHash объектов IIS Admin Base, необходимо использовать десятичное значение 5506.
  3. Необходимо создать новые строки метабазы свойства, SSLStoreNameдля соответствующего веб-узла. Присвоено строковое значение МоиSSLStoreName . Можно либо задать SSLStoreName через объектов IIS Admin (например, в сценарии ADSI) или IIS Admin Baseobjects. Для использования SSLStoreName базовых объектов IIS Admin, используйте десятичное значение 5511.




Код на языке 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 handle

HCERTSTORE hStoreHandle;   

//--------------------------------------------------------------------
// Pointer to a certificate

PCCERT_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 certificate
pHash = 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




Введите свойство SSLCertHash в метабазу кода на языке C

В следующем примере кода описывается использование объектов IIS Admin Base Выбор метода SSLCertHash в метабазе. В следующем коде используется массив произвольных двоичных как отпечатоксертификата. Фактический код будет использовать значения отпечатка , который можно получить при выполнении кода в разделе «Получить отпечаток из сертификата проверки подлинности сервера». В зависимости от того, как метод SetData определить во время компиляции можно установить SSLCertHash, либо если уже настроен протокол SSL для веб-узла, вы можете получить SSLCertHash , существует. Возврат SSLCertHashmethod существующий 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");
#endif

clean:
	pIMeta->CloseKey(MyHandle); 
	pIMeta->SaveData();
	pIMeta->Release();
	CoUninitialize();

	return 1;
}



Ссылки

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

Свойства

Код статьи: 313624 - Последний отзыв: 20 января 2014 г. - Revision: 5.0
Информация в данной статье относится к следующим продуктам.
  • Microsoft Internet Information Services 5.0
Ключевые слова: 
kbcrypt kbapi kbhowtomaster kbsecurity kbisapiext kbhowto kbmt KB313624 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Данная статья переведена с использованием программного обеспечения Майкрософт для машинного перевода и, возможно, отредактирована посредством технологии Community Translation Framework (CTF). Корпорация Майкрософт предлагает вам статьи, обработанные средствами машинного перевода, отредактированные членами сообщества Майкрософт и переведенные профессиональными переводчиками, чтобы вы могли ознакомиться со всеми статьями нашей базы знаний на нескольких языках. Статьи, переведенные с использованием средств машинного перевода и отредактированные сообществом, могут содержать смысловое, синтаксические и (или) грамматические ошибки. Корпорация Майкрософт не несет ответственности за любые неточности, ошибки или ущерб, вызванные неправильным переводом контента или его использованием нашими клиентами. Подробнее об CTF можно узнать по адресу http://support.microsoft.com/gp/machine-translation-corrections/ru.
Эта статья на английском языке: 313624

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

 

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