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

Код статьи: 313624 - Список продуктов, к которым относится данная статья.
Развернуть все | Свернуть все

На этой странице

Важные Эта статья содержит сведения об изменении метабазы. Перед изменением метабазы убедитесь, что резервная копия, вы можете восстановления в случае возникновения проблем. Для получения сведений о том, как это сделать, см. Раздел справки «Архивирование и восстановление конфигурации» в консоли управления MMC (MMC).

Аннотация


Данная статья содержит пошаговые инструкции по программно создать и затем установить Secure Sockets Layer (SSL) сертификаты для Internet Information Server (IIS). Хотя IIS версии 4.0 и IIS версии 5.0 каждый предоставляют пользовательский интерфейс (UI) для создания, а затем в Установите сертификаты SSL сервер можно также выполнить задачу программно.



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

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



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

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

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



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




Этапы настройки IIS

Сохранить сертификат в хранилище, необходимо настроить IIS, как показано ниже:
  1. Использование CertGetCertificateContextProperty()метод для получения значений Отпечаток свойства и CERT_HASH_PROP_ID свойство. В CertGetCertificateContextProperty() функция использует CryptHashCertificate() метод для вычисления значения для CERT_HASH_PROP_ID свойство. Если хэш-значение не существует, CertGetCertificateContextProperty() Возвращает SHA1 алгоритм.
  2. Необходимо создать новые двоичные свойства метабазы, SSLCertHash, который соответствует веб-узла. Набор SSLCertHash для сертификата Отпечаток полученным на шаге 1 в этом разделе. При возникновении данной проблемы неправильно определяет схему SSLCertHash Свойство как развернутый null завершающаяся нулем, вместо того, как двоичные данные, а затем объектов IIS Admin нельзя использовать для импорта SSLCertHash. Можно использовать только для объектов IIS Admin Base Чтобы импортировать это значение. Для использования SSLCertHash с помощью объектов IIS Admin Base необходимо использовать десятичное значение 5506.
  3. Необходимо создать новое строковое свойство метабазы, SSLStoreName, для соответствующего веб-узла. Набор SSLStoreName Строка МОЙ значение. Вы можете установить SSLStoreName через объектов IIS Admin (например, в сценарии ADSI) или через службы IIS Admin Base объекты. Для использования 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




Код на языке c для ввода SSLCertHash свойства в метабазе

В следующем примере кода описывается, как использовать службы IIS Admin Base объекты, для установки SSLCertHash метод в метабазе. В следующем коде используется произвольный двоичный массив в качестве сертификата Отпечаток. Фактический код будет использовать Отпечаток значение, которое можно получить при выполнении кода «получить Раздел отпечаток сертификата проверки подлинности сервера». В зависимости от того, как определения Метод SetData метод во время компиляции, можно либо задать SSLCertHash, или если уже настроен протокол SSL для веб-узла, вы можете получить SSLCertHash который существует. SSLCertHash существующий метод возврата 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 - Последнее изменение :: 7 июня 2011 г. - Редакция: 4.0
Информация в данной статье относится к следующим продуктам.
  • Microsoft Internet Information Services 5.0
Ключевые слова: 
kbcrypt kbapi kbhowtomaster kbsecurity kbisapiext kbhowto kbmt KB313624 KbMtru
Переведено с помощью машинного перевода
ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.
Эта статья на английском языке:313624

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