프로그래밍 방식으로 인터넷 정보 서버(IIS)에 대한 SSL 인증서를 설치하는 방법

기술 자료 번역 기술 자료 번역
기술 자료: 313624 - 이 문서가 적용되는 제품 보기.
모두 확대 | 모두 축소

이 페이지에서

중요한 이 문서에서는 메타베이스의 편집에 대한 정보가 들어 있습니다. 메타베이스를 편집하기 전에 문제가 발생하는 경우 복원할 수 있는 백업 복사본이 있는지 확인하십시오. 이렇게 하는 방법에 대한 자세한 내용은 Microsoft 관리 콘솔(MMC) "구성 백업/복원" 도움말 항목을 참고하십시오.

요약


이 문서에서는 프로그래밍 방식으로 만드는 방법을 설명하고 인터넷 정보 서버 (IIS)를 위한 소켓 계층 (SSL) 보안 설치하려면 인증서를. IIS 버전 4.0 및 IIS 버전 5.0 각 사용자 인터페이스 (UI) 만들 제공하는 동안 다음 SSL 서버 인증서를 설치하려면 사용자가 작업을 프로그래밍 방식으로 완료할 수도 있습니다.



만드는 단계 및 다음 SSL 인증서 설치

프로그래밍 방식으로 만들고 다음 IIS 서버에 대한 SSL 인증서를 설치하려면 다음 이 단계를 수행하십시오.
  1. 서버 인증서를 발급하도록 인증 기관에 요청을 보내야 합니다. 인증서를 이미 다음 사용자가 IIS 서버에 파일을 저장할 경우 요청을 보내지 마십시오.
  2. 적절한 인증서 저장소에 인증서를 가져옵니다.
  3. 1단계에서 얻은 인증서를 사용하도록 IIS를 구성하십시오.



만들려면 IIS 구성 및 SSL 설치하려면 다음 인증서

경고 메타베이스를 잘못 편집하면 메타베이스를 사용하는 모든 제품을 다시 설치해야 하는 심각한 문제가 발생할 수 있습니다. Microsoft는 메타베이스를 잘못 편집함으로써 발생하는 문제를 해결할 수 있음을 보증하지 않습니다. 메타베이스의 수정에 따른 모든 책임은 편집하십시오.

참고 편집하기 전에 항상 메타베이스를 백업하십시오. 만들려면 IIS를 구성하려면 다음과 같이 및 SSL 설치하려면 인증서:
  1. Microsoft Windows Crypto API 지문 얻을 수 있는 인증서의 속성을.
  2. 지문 값을 SSLCertHash, 메타베이스 속성을 설정해야 합니다.
  3. 원하는 저장소를 SSLStoreName, 메타베이스 속성을 설정해야 합니다.
코드 샘플, 인증서의 지문 얻으려면 다음 문서의 섹션을 참조하십시오 다음 SSLCertHash 속성을 얻을 수:
C Code to Obtain the Thumbprint of a Server Authentication Certificate
C Code to Enter the SSLCertHash Property into the Metabase



특정 웹 사이트에서 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 속성에 대한 값을 계산합니다. 해시 값이 없는 경우 SHA1 알고리즘을 CertGetCertificateContextProperty()가 반환합니다.
  2. 새 이진 메타베이스 속성을, 웹 사이트에 해당하는 SSLCertHash, 만들어야 합니다. 이 절의 1단계에서 얻은 지문 인증서 SSLCertHash를 설정하십시오. 이 문제가 발생하면 스키마를 잘못 SSLCertHash 속성이 있는 확장된 null 문자로 끝나는 문자열과 대신 이진 데이터로 지정하고 IIS 관리 개체 SSLCertHash 가져올 수 없습니다. IIS Admin 자료 개체에 대해서만 이 값을 가져올 수 있습니다. SSLCertHash IIS Admin 자료 개체를 사용하려면 5506 10진수 값을 사용해야 합니다.
  3. 새 문자열 메타베이스 속성을, SSLStoreName, 해당 웹 사이트를 만들어야 합니다. SSLStoreNameMY 값을 문자열로 설정하십시오. IIS 관리 개체 (예를 들어, ADSI 스크립트) 또는 IIS Admin 기본 개체를 통해 SSLStoreName 중 하나를 설정할 수 있습니다. 5511 10진수 값을 사용하여 SSLStoreName IIS Admin 기본 개체를 사용합니다.




서버 인증 인증서 지문 얻는 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 속성 입력

다음 샘플 코드에서는 SSLCertHash 메서드는 메타베이스에서 설정하려면 IIS 관리 기본 개체를 사용하는 방법을 설명합니다. 다음 코드에서는 인증서 지문 임의의 이진 배열을 사용합니다. 실제 코드 구하는 경우 지문 중 있는 서버 인증 인증서 "섹션에서 코드를 실행할 때 얻은 지문 값을 사용할 수 있습니다. 컴파일 타임에 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");
#endif

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

	return 1;
}



참조

추가 정보는 다음 문서 번호를 클릭하여 Microsoft 기술 자료에서 확인하십시오:
315588클라이언트 인증서를 사용하여 ASP.NET 응용 프로그램의 보안 방법

속성

기술 자료: 313624 - 마지막 검토: 2006년 7월 11일 화요일 - 수정: 2.2
본 문서의 정보는 다음의 제품에 적용됩니다.
  • Microsoft Internet Information Server 4.0
  • Microsoft Internet Information Services 5.0
키워드:?
kbmt kbcrypt kbapi kbhowtomaster kbsecurity kbisapiext kbhowto KB313624 KbMtko
기계 번역된 문서
중요: 본 문서는 전문 번역가가 번역한 것이 아니라 Microsoft 기계 번역 소프트웨어로 번역한 것입니다. Microsoft는 번역가가 번역한 문서 및 기계 번역된 문서를 모두 제공하므로 Microsoft 기술 자료에 있는 모든 문서를 한글로 접할 수 있습니다. 그러나 기계 번역 문서가 항상 완벽한 것은 아닙니다. 따라서 기계 번역 문서에는 마치 외국인이 한국어로 말할 때 실수를 하는 것처럼 어휘, 구문 또는 문법에 오류가 있을 수 있습니다. Microsoft는 내용상의 오역 또는 Microsoft 고객이 이러한 오역을 사용함으로써 발생하는 부 정확성, 오류 또는 손해에 대해 책임을 지지 않습니다. Microsoft는 이러한 문제를 해결하기 위해 기계 번역 소프트웨어를 자주 업데이트하고 있습니다.

피드백 보내기

 

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