ID do artigo: 313624 - Última revisão: terça-feira, 11 de julho de 2006 - Revisão: 2.2

Como instalar certificados SSL por meio de programação para o Internet Information Server (IIS)

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Recolher tudo
importante Este artigo contém informações sobre como editar a metabase. Antes de editar a metabase, verifique se você tem uma cópia de backup que você pode restaurar se ocorrer um problema. Para obter informações sobre como fazer isso, consulte o tópico da Ajuda "backup/restauração de configuração" no Microsoft Management Console (MMC).

Sumário


Este artigo passo a passo descreve como criar programaticamente e, em seguida, para instalar o Secure Sockets Layer (SSL) certificados para o Internet Information Server (IIS). Enquanto o IIS versão 4.0 e IIS versão 5.0 cada fornecer uma interface de usuário (UI) para que você crie e, em seguida, para instalar certificados de servidor SSL, você também pode completar a tarefa por meio de programação.



Passos para criar e depois para instalar certificados SSL

Para criar por programação e, em seguida, para instalar certificados SSL para servidor IIS, execute estas etapas:
  1. Você deve enviar uma solicitação para a autoridade de certificação para emitir um certificado de servidor. Se você já tiver o certificado e, em seguida, você armazena no arquivo no servidor IIS, não envie a solicitação.
  2. Importe o certificado para o armazenamento de certificado apropriado.
  3. Configure o IIS para usar o certificado que você obteve na etapa 1.



Configurar o IIS para criar e depois instalar o SSL certificados

Aviso Se você editar a metabase incorretamente, você pode causar problemas sérios que talvez exijam a reinstalação de qualquer produto que usa a metabase. A Microsoft não garante que problemas resultantes se você editar incorretamente a metabase podem ser solucionados. Edite a metabase de sua responsabilidade.

Observação Sempre fazer backup da metabase antes de editá-lo. Siga as etapas para configurar o IIS para criar e, em seguida instalar o SSL certificados:
  1. Usar APIs de criptografia do Microsoft Windows para obter impressão digital propriedade do certificado.
  2. Você deve definir a propriedade de metabase do IIS, SSLCertHash , como o valor de impressão digital .
  3. Você deve definir a propriedade de metabase do IIS, SSLStoreName , para o armazenamento que você deseja usar.
Consulte as seguintes seções de artigo para amostras de código para obter uma impressão digital do certificado e obter a propriedade SSLCertHash :
C Code to Obtain the Thumbprint of a Server Authentication Certificate
C Code to Enter the SSLCertHash Property into the Metabase



Etapas para ativar a SSL em um site específico

Depois de executar as etapas na seção "Configurar IIS para criar e depois para instalar certificados SSL", em seguida, você pode habilitar SSL em um site específico ou em uma pasta específica. Para fazer isso, você deve habilitar SSL opções na pasta que você deseja usar. As etapas a seguir correspondem a cada etapa que é descrita na seção "Configurar IIS para criar e depois para instalar certificados SSL":
  1. Quando você chamar o método CEnroll::createPKCS10() , a solicitação de certificado é criada. Definir o uso como o seguinte valor predefinido: szOID_PKIX_KP_SERVER_AUTH :
    #define szOID_PKIX_KP_SERVER_AUTH       "1.3.6.1.5.5.7.3.1"		
  2. Quando você chama o método ICertRequest:: enviar () , uma solicitação para o certificado é enviada à autoridade de certificação.
  3. O certificado é recuperado da autoridade de certificação e, em seguida, ele é instalado no armazenamento apropriado. O servidor IIS Assistente de certificado procura somente certificados que pode usar para autenticação de servidor no armazenamento de certificado de computador local.




Etapas para configurar o IIS

Depois de salvar o certificado para o armazenamento, você deve configurar IIS da seguinte maneira:
  1. Use o método CertGetCertificateContextProperty() para obter os valores da propriedade impressão digital e a propriedade CERT_HASH_PROP_ID . A função CertGetCertificateContextProperty() usa o método CryptHashCertificate() para calcular o valor da propriedade CERT_HASH_PROP_ID . Se o valor HASH não existir, CertGetCertificateContextProperty() retorna o algoritmo SHA1 .
  2. Você deve criar uma nova propriedade da metabase binária, SSLCertHash , que corresponde ao site do. Defina SSLCertHash para o certificado impressão digital que você obteve na etapa 1 desta seção. Quando esse problema ocorre, o esquema incorretamente Especifica a propriedade SSLCertHash como uma nula terminada seqüência expandida, em vez de como dados binários, e em seguida, você não pode usar objetos Admin do IIS para importar SSLCertHash . Você pode usar somente os objetos base de administração IIS para importar esse valor. Para usar SSLCertHash com objetos base de administração do IIS, você deve usar o valor decimal, 5506.
  3. Você deve criar uma nova seqüência de caracteres propriedade da metabase, SSLStoreName , para o site correspondente. Definir SSLStoreName para a seqüência Meu valor. Você pode definir SSLStoreName através de objetos Admin do IIS (por exemplo, em script de ADSI) ou através de objetos base de administração do IIS. Para usar SSLStoreName com objetos base de administração do IIS, use o valor decimal, 5511.




Código c para obter impressão digital de um certificado de autenticação de servidor

O seguinte código Microsoft C exemplo descreve como obter a propriedade de impressão digital de um certificado de autenticação do servidor:
#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ódigo c para inserir a propriedade SSLCertHash para a Metabase

O código de exemplo a seguir descreve como usar objetos base de administração do IIS para definir o método SSLCertHash na metabase. O código a seguir usa uma matriz binária arbitrária como um impressão digital do certificado. Código real usaria o valor de impressão digital que você obtém quando você executa o código na seção "Obter a impressão digital de um Server Authentication Certificate". Dependendo de como você define o método SetData em tempo de compilação, você pode definir SSLCertHash ou, se você já configurado a SSL para o site da Web, você pode obter SSLCertHash que existe. 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;
}



Referências

Para obter mais informações, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
315588  (http://support.microsoft.com/kb/315588/ ) Como proteger um aplicativo ASP.NET usando certificados do lado do cliente


A informação contida neste artigo aplica-se a:
  • Microsoft Internet Information Server 4.0
  • Microsoft Internet Information Services 5.0
Palavras-chave: 
kbmt kbcrypt kbapi kbhowtomaster kbsecurity kbisapiext kbhowto KB313624 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 313624  (http://support.microsoft.com/kb/313624/en-us/ )