Como programaticamente instalar certificados de SSL para o Internet Information Server (IIS)

Traduções de Artigos Traduções de Artigos
Artigo: 313624 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

importante Este artigo contém informações sobre como editar a metabase. Antes de editar a metabase, verifique se tem uma cópia de segurança que pode restaurar se ocorrer um problema. Para obter informações sobre como efectuar este procedimento, consulte o tópico de ajuda "configuração de cópia de segurança/restauro" na consola de gestão da Microsoft.

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 fornecem uma interface de utilizador (UI) para criar e, em seguida, para instalar certificados de servidor SSL, pode também concluir a tarefa através de programação.



Passos para criar e depois instalar certificados SSL

Para criar programaticamente e, em seguida, instalar certificados de SSL para servidor de IIS, siga estes passos:
  1. Tem de enviar um pedido à autoridade de certificação para emitir um certificado de servidor. Se já tiver o certificado e, em seguida, guardar no ficheiro no servidor de IIS, não envie o pedido.
  2. Importe o certificado para arquivo de certificados apropriado.
  3. Configure o IIS para utilizar o certificado obtido no passo 1.



Configurar o IIS para criar e, em seguida, instalar o SSL certificados

aviso Se editar a metabase incorrectamente, poderá provocar problemas graves que poderão forçar a reinstalação qualquer produto que utiliza a metabase. Microsoft não garante que problemas resultantes da incorrecta editar a metabase podem ser resolvidos. Edite a metabase por sua conta e risco.

Nota Sempre uma cópia da metabase antes de o editar de segurança. Siga estes passos para configurar o IIS para criar e, em seguida instalar o SSL certificados:
  1. Utilizar APIs do Microsoft Windows criptográfico para obter o thumbprint propriedade do certificado.
  2. Tem de definir a propriedade da metabase do IIS, SSLCertHash , o valor de thumbprint .
  3. Tem de definir a propriedade da metabase do IIS, SSLStoreName , para o arquivo que pretende utilizar.
Consulte as secções seguintes do artigo para obter um thumbprint do certificado, exemplos de código 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



Passos para activar SSL num determinado Web Site

Depois de efectuar os passos na secção "Configurar o IIS para criar e, em seguida, para instalar certificados SSL", em seguida, é possível activar SSL num determinado site ou numa determinada pasta. Para o fazer, tem de activar o SSL opções na pasta que pretende utilizar. Os seguintes passos correspondem em cada passo descrito na secção "Configurar o IIS para criar e, em seguida, para instalar certificados SSL":
  1. Quando chamar o método de CEnroll::createPKCS10() , é criado o pedido de certificado. Definir a utilização para o valor predefinido seguinte: szOID_PKIX_KP_SERVER_AUTH :
    #define szOID_PKIX_KP_SERVER_AUTH       "1.3.6.1.5.5.7.3.1"		
  2. Quando chama o método ICertRequest:: Submeter () , é submetido um pedido para o certificado à autoridade de certificação.
  3. É obter o certificado da autoridade de certificação e, em seguida, é instalado no arquivo de adequado. O servidor de IIS ' Assistente de certificados ' procurará apenas certificados que pode utilizar para autenticação de servidor no arquivo de certificados computador local.




Passos para configurar o IIS

Depois de guardar o certificado no arquivo, tem de configurar o IIS da seguinte forma:
  1. Utilize o método CertGetCertificateContextProperty() para obter os valores da propriedade thumbprint e a propriedade CERT_HASH_PROP_ID . A função CertGetCertificateContextProperty() utiliza o método CryptHashCertificate() para calcular o valor da propriedade CERT_HASH_PROP_ID . Se o valor HASH não existir, CertGetCertificateContextProperty() devolve o algoritmo SHA1 .
  2. Tem de criar uma nova binário propriedade da metabase, SSLCertHash , que corresponde ao Web site. Defina SSLCertHash para o certificado thumbprint obtido no passo 1 desta secção. Quando este problema ocorre, o esquema Especifica incorrectamente a propriedade SSLCertHash como uma cadeia terminada nulo expandida, em vez de como dados binários, e, em seguida, não pode utilizar objectos de administração do IIS para importar SSLCertHash . Pode utilizar apenas objectos de base de administração do IIS para importar este valor. Para utilizar SSLCertHash com objectos de base de administração do IIS, tem de utilizar o valor decimal, 5506.
  3. Tem de criar uma nova cadeia de propriedade da metabase, SSLStoreName , para o Web site correspondente. Defina SSLStoreName para a cadeia de valor MY . Pode definir ou SSLStoreName através de objetos Admin do IIS (por exemplo, no script de ADSI) ou através de objectos de base de administração do IIS. Para utilizar SSLStoreName com objectos de base de administração do IIS, utilize o valor decimal, 5511.




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

O código de Microsoft C do exemplo seguinte descreve como obter a propriedade de thumbprint do certificado de autenticação de 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 introduzir a propriedade SSLCertHash para a Metabase

O código de exemplo seguinte descreve como utilizar objectos de base de administração do IIS para definir o método SSLCertHash na metabase. O código seguinte utiliza uma matriz binária arbitrária como um certificado de thumbprint . Código utilizaria o valor de thumbprint obterá quando executa o código na secção "Obter o thumbprint de uma autenticação de certificado de servidor". Dependendo de como definir o método SetData durante a compilação, ou pode definir SSLCertHash ou, se já tiver configurado o SSL para o Web site, 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 de artigo que se segue para visualizar o artigo na Microsoft Knowledge Base:
315588Como proteger uma aplicação do ASP.NET utilizando certificados do lado do cliente

Propriedades

Artigo: 313624 - Última revisão: 11 de julho de 2006 - Revisão: 2.2
A informação contida neste artigo aplica-se a:
  • Microsoft Internet Information Server 4.0
  • Serviços de informação Internet 5.0 da Microsoft
Palavras-chave: 
kbmt kbcrypt kbapi kbhowtomaster kbsecurity kbisapiext kbhowto KB313624 KbMtpt
Traduçã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 revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 313624

Submeter comentários

 

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