Trabalhando com certificados

Para programar a segurança do WCF (Windows Communication Foundation), os certificados digitais X.509 são normalmente usados para autenticar clientes e servidores, criptografar e assinar mensagens digitalmente. Este tópico explica rapidamente as funcionalidades dos certificados digitais X.509 e como usá-los no WCF. Inclui também links para tópicos que explicam esses conceitos mais detalhadamente ou que mostram como realizar tarefas comuns usando o WCF e certificados.

Em resumo, um certificado digital faz parte de uma PKI (infraestrutura de chave pública), que é um sistema de certificados digitais, autoridades de certificação e outras autoridades de registro que verificam e autenticam a validade de cada parte envolvida em uma transação eletrônica por meio do uso da criptografia de chave pública. Uma autoridade de certificação emite certificados e cada certificado tem um conjunto de campos que contêm dados, como a entidade (a entidade para a qual o certificado é emitido), as datas de validade (quando o certificado é válido), o emissor (a entidade que emitiu o certificado) e uma chave pública. No WCF, cada uma dessas propriedades é processada como uma Claim e cada declaração é dividida em dois tipos: identidade e direito. Para obter mais informações sobre os certificados X.509, confira Certificados de chave pública X.509. Para obter mais informações sobre Declarações e Autorização no WCF, confira Gerenciando declarações e autorização com o modelo de identidade. Para obter mais informações sobre como implementar uma PKI, consulte PKI corporativa com serviços de certificados do Active Directory do Windows Server 2012 R2.

A função principal de um certificado é autenticar a identidade do proprietário do certificado para outras pessoas. Um certificado contém a chave pública do proprietário, enquanto o proprietário retém a chave privada. A chave pública pode ser usada para criptografar as mensagens enviadas para o proprietário do certificado. Somente o proprietário tem acesso à chave privada; portanto, somente o proprietário pode descriptografar essas mensagens.

Os certificados devem ser emitidos por uma autoridade de certificação, que geralmente é um emissor de certificados terceirizado. Em um domínio do Windows, uma autoridade de certificação é incluída e pode ser usada para emitir certificados para computadores no domínio.

Exibir certificados

Para trabalhar com certificados, geralmente é necessário exibi-los e examinar suas propriedades. Isso é feito facilmente com a ferramenta de snap-in do Console de Gerenciamento Microsoft (MMC). Para saber mais, consulte Como Exibir Certificados com o Snap-in do MMC.

Repositórios de certificados

Os certificados estão localizados em repositórios. Dois grandes repositórios de certificado existem e são divididos em sub-repositórios. Se você for o administrador em um computador, poderá exibir os dois principais repositórios usando a ferramenta do snap-in do MMC. Os não administradores podem exibir somente o repositório do usuário atual.

  • O repositório do computador local. Contém os certificados acessados por processos de máquina, como ASP.NET. Use este local para armazenar os certificados que autenticam o servidor para clientes.

  • O repositório do usuário atual. Os aplicativos interativos geralmente colocam certificados aqui para o usuário atual do computador. Se você estiver criando um aplicativo cliente, aqui é onde você normalmente coloca os certificados que autenticam um usuário para um serviço.

Esses dois repositórios são divididos em sub-repositórios. O mais importante deles ao programar com o WCF inclui:

  • Autoridades de Certificação Raiz Confiáveis. Você pode usar os certificados nesse repositório para criar uma cadeia de certificados, que podem ser rastreados para um certificado de autoridade de certificação nesse repositório.

    Importante

    O computador local implicitamente confia em qualquer certificado colocado nesse repositório, mesmo se o certificado não vier de uma autoridade de certificação de terceiros confiável. Por esse motivo, não coloque nenhum certificado nesse repositório a menos que você confie totalmente no emissor e entenda as consequências.

  • Pessoal. Esse repositório é usado para os certificados associados com um usuário de um computador. Geralmente, esse repositório é usado para os certificados emitidos por um dos certificados da autoridade de certificação localizados no repositório Autoridades de Certificação Confiáveis. Como alternativa, um certificado localizado aqui pode ser emitido por conta própria e confiável por um aplicativo.

Para obter mais informações sobre repositórios de certificados, confira Repositórios de certificados.

Selecionar um repositório

Selecionar onde armazenar um certificado depende de como e quando o serviço ou o cliente é executado. As seguintes regras gerais se aplicam:

  • Se o serviço WCF está hospedado em um serviço Windows, use o repositório do computador local. Observe que os privilégios de administrador são necessários para instalar certificados no repositório do computador local.

  • Se o serviço ou o cliente é um aplicativo executado em uma conta de usuário, use o repositório do usuário atual.

Repositórios de acesso

Os repositórios são protegidos por listas de controle de acesso (ACLs), como pastas em um computador. Ao criar um serviço hospedado pelos Serviços de Informações da Internet (IIS), o processo ASP.NET é executado na conta ASP.NET. Essa conta deve ter acesso ao repositório que contém os certificados que um serviço usa. Cada um dos principais repositórios é protegido por uma lista de acesso padrão, mas as listas podem ser modificadas. Se você criar uma função separada para acessar um repositório, deverá conceder permissão de acesso a essa função. Para saber como modificar a lista de acesso usando a ferramenta WinHttpCertConfig.exe, confira Como criar certificados temporários para uso durante o desenvolvimento.

Confiança de cadeia e autoridades de certificado

Os certificados são criados em uma hierarquia onde cada certificado individual está vinculado à CA que emitiu o certificado. Este é o link para o certificado da CA. O certificado da CA vincula-se à CA que emitiu o certificado original da CA. Esse processo é repetido até que o certificado da CA seja alcançado. O certificado da CA é inerentemente de confiança.

Os certificados digitais são usados para autenticar uma entidade confiando nessa hierarquia, também chamada de cadeia de confiança. Você pode visualizar a cadeia de qualquer certificado usando o snap-in do MMC clicando duas vezes em qualquer certificado e clicando na guia Caminho do certificado. Para obter mais informações sobre como importar cadeias de certificados para uma autoridade de certificação, consulte Como: especificar a cadeia de certificados da autoridade de certificação usada para verificar assinaturas.

Observação

Qualquer emissor pode ser designado uma autoridade confiável colocando o certificado do emissor no repositório de certificados da autoridade confiável.

Desabilitar a confiança de cadeia

Ao criar um novo serviço, você pode usar um certificado que não seja emitido por um certificado raiz confiável ou o próprio certificado de emissão pode não estar no repositório das Autoridades de Certificação Confiáveis. Somente para a finalidade de desenvolvimento, você pode desativar temporariamente o mecanismo que verifica a cadeia de confiança para um certificado. Para fazer isso, defina a propriedade CertificateValidationMode para PeerTrust ou PeerOrChainTrust. Qualquer um dos modos especifica que o certificado pode ser emitido por conta própria (confiança de par) ou parte de uma cadeia de confiança. Você pode definir a propriedade em qualquer uma das seguintes classes.

Classe Propriedade
X509ClientCertificateAuthentication X509ClientCertificateAuthentication.CertificateValidationMode
X509PeerCertificateAuthentication X509PeerCertificateAuthentication.CertificateValidationMode
X509ServiceCertificateAuthentication X509ServiceCertificateAuthentication.CertificateValidationMode
IssuedTokenServiceCredential IssuedTokenServiceCredential.CertificateValidationMode

Também é possível definir a propriedade usando configuração. Os seguintes elementos são usados para especificar o modo de validação:

Autenticação personalizada

A propriedade CertificateValidationMode também permite que você personalize como os certificados são autenticados. Por padrão, o nível é definido como ChainTrust. Para usar o valor Custom, você também deverá definir o atributo CustomCertificateValidatorType para um assembly e um tipo usados para validar o certificado. Para criar um validador personalizado, você deverá herdar da classe abstrata X509CertificateValidator.

Ao criar um autenticador personalizado, o método mais importante para substituição é o método Validate. Para obter um exemplo de autenticação personalizada, confira a amostra Validador de certificado X.509. Para obter mais informações, confira Credencial personalizada e validação de credenciais.

Usar o cmdlet New-SelfSignedCertificate do PowerShell para criar uma cadeia de certificados

O cmdlet New-SelfSignedCertificate do PowerShell cria certificados X.509 e pares de chave privada/chave pública. Você pode salvar a chave privada no disco e, em seguida, usá-la para emitir e assinar novos certificados, simulando uma hierarquia de certificados encadeados. O cmdlet destina-se ao uso apenas como auxílio no desenvolvimento de serviços e nunca deve ser usado para criar certificados para implantação real. Ao desenvolver um serviço WCF, use as etapas a seguir para criar uma cadeia de confiança com o cmdlet New-SelfSignedCertificate.

  1. Crie um certificado de autoridade raiz temporária (autoassinado) usando o cmdlet New-SelfSignedCertificate. Salve a chave privada no disco.

  2. Use o novo certificado para emitir outro certificado que contém a chave pública.

  3. Importe o certificado de autoridade no repositório de Autoridades de Certificação Confiáveis.

  4. Para obter instruções passo a passo, confira Como criar certificados temporários para uso durante o desenvolvimento.

Qual certificado usar?

As perguntas comuns sobre certificados são qual certificado usar e por quê. A resposta depende de se você está programando um cliente ou serviço. As informações a seguir fornecem uma orientação geral e não são uma resposta completa a essas perguntas.

Certificados de serviço

Os certificados de serviço têm a tarefa principal de autenticar o servidor para clientes. Uma das verificações iniciais feitas quando um cliente autentica um servidor é comparar o valor do campo Entidade com o URI (Uniform Resource Identifier) usado para contatar o serviço: o DNS de ambos deve ser correspondente. Por exemplo, se o URI do serviço for http://www.contoso.com/endpoint/, o campo Assunto também deverá conter o valor www.contoso.com.

Observe que o campo pode conter vários valores, cada um prefixado com uma inicialização para indicar o valor. Mais comumente, a inicialização é "CN" para nome comum, por exemplo, CN = www.contoso.com. Também é possível que o campo Entidade fique em branco. Nesse caso, o campo Nome Alternativo da Entidade pode conter o valor do Nome DNS.

Observe também que o valor do campo Finalidades do certificado deve incluir um valor apropriado, como "Autenticação do Servidor" ou "Autenticação do Cliente".

Certificados do cliente

Os certificados de cliente não são normalmente emitidos por uma autoridade de certificação de terceiros. Em vez disso, o repositório Pessoal do local atual do usuário geralmente contém os certificados colocados lá por uma autoridade raiz, com uma finalidade de “Autenticação do cliente”. O cliente pode usar esse certificado quando a autenticação mútua é necessária.

Revogação online e revogação offline

Validade de certificado

Cada certificado é válido somente por um período determinado, chamado de período de validade. O período de validade é definido pelos campos Válido de e Válido até de um certificado X.509. Durante a autenticação, o certificado é verificado para determinar se o certificado ainda está dentro do período de validade.

Lista de revogação de certificados

A qualquer momento durante o período de validade, a autoridade de certificação pode revogar um certificado. Isso pode ocorrer por muitas razões, como um comprometimento da chave privada do certificado.

Quando isso ocorre, todas as cadeias que descenderem do certificado revogado também tornam-se inválidas e não são confiáveis durante os procedimentos de autenticação. Para descobrir quais certificados são revogados, cada emissor publica uma CRL (lista de certificados revogados) com carimbo de data e hora. A lista pode ser marcada usando a revogação online ou offline definindo a propriedade RevocationMode ou DefaultRevocationMode das seguintes classes para um dos valores de enumeração X509RevocationMode: as classes X509ClientCertificateAuthentication, X509PeerCertificateAuthentication, X509ServiceCertificateAuthentication e IssuedTokenServiceCredential. O valor padrão para todas as propriedades é Online.

Você também pode definir o modo na configuração usando o atributo revocationMode de <autenticação> (de <serviceBehaviors>) e <autenticação> (dos <endpointBehaviors>).

O método SetCertificate

No WCF, em geral, você precisa especificar um certificado ou um conjunto de certificados que um serviço ou um cliente deve usar para autenticar, criptografar ou assinar digitalmente uma mensagem. Você pode fazer isso por meio de programação usando o método SetCertificate de várias classes que representam certificados X.509. As seguintes classes usam o método SetCertificate para especificar um certificado.

Classe Método
PeerCredential SetCertificate
X509CertificateInitiatorClientCredential SetCertificate
X509CertificateRecipientServiceCredential SetCertificate
X509CertificateInitiatorServiceCredential
SetCertificate

O método SetCertificate funciona designando um local de repositório e um repositório, um tipo “find” (parâmetro x509FindType) que especifica um campo do certificado e um valor a ser localizado no campo. Por exemplo, o código a seguir cria uma instância de ServiceHost e define o certificado de serviço usado para autenticar o serviço em clientes com o método SetCertificate.

Uri baseAddress = new Uri("http://cohowinery.com/services");
ServiceHost sh = new ServiceHost(typeof(CalculatorService), baseAddress );
sh.Credentials.ServiceCertificate.SetCertificate(
StoreLocation.LocalMachine, StoreName.My,
X509FindType.FindBySubjectName, "cohowinery.com");
Dim baseAddress As New Uri("http://cohowinery.com/services")
Dim sh As New ServiceHost(GetType(CalculatorService), baseAddress)
sh.Credentials.ServiceCertificate.SetCertificate( _
StoreLocation.LocalMachine, StoreName.My, _
X509FindType.FindBySubjectName, "cohowinery.com")

Vários certificados com o mesmo valor

Um repositório pode conter vários certificados com o mesmo nome de assunto. Isso significa que, se você especificar que o x509FindType é FindBySubjectName ou FindBySubjectDistinguishedName, e mais de um certificado tiver o mesmo valor, uma exceção será gerada porque não existe nenhuma maneira de distinguir qual certificado é necessário. Você pode solucionar isso configurando o x509FindType como FindByThumbprint. O campo de impressão digital contém um valor exclusivo que pode ser usado para localizar um certificado específico em um repositório. No entanto, isso tem sua própria desvantagem: se o certificado for revogado ou renovado, o método SetCertificate falhará porque a impressão digital também será. Ou se o certificado não for mais válido, a autenticação falhará. A maneira de solucionar isso é definir o parâmetro x590FindType como FindByIssuerName e especificar o nome do emissor. Se nenhum emissor específico for necessário, você também poderá definir um dos outros valores de enumeração X509FindType, como FindByTimeValid.

Certificados na configuração

Você também pode definir certificados usando configuração. Se você estiver criando um serviço, as credenciais, incluindo certificados, serão especificadas em <serviceBehaviors>. Quando você está programando um cliente, os certificados são especificados em <endpointBehaviors>.

Mapear um certificado para uma conta de usuário

Um recurso do IIS e do Active Directory é a capacidade para mapear um certificado para uma conta de usuário do Windows. Para obter mais informações sobre a funcionalidade, confira Mapear certificados para contas de usuário.

Para obter mais informações sobre como usar o mapeamento do Active Directory, confira Mapeando certificados do cliente com o mapeamento do serviço de diretório.

Com esse recurso ativado, você poderá definir a propriedade MapClientCertificateToWindowsAccount da classe X509ClientCertificateAuthentication como true. Na configuração, você pode definir o atributo mapClientCertificateToWindowsAccount do elemento <authentication> como true, conforme mostrado no código a seguir.

<serviceBehaviors>
 <behavior name="MappingBehavior">
  <serviceCredentials>
   <clientCertificate>
    <authentication certificateValidationMode="None" mapClientCertificateToWindowsAccount="true" />
   </clientCertificate>
  </serviceCredentials>
 </behavior>
</serviceBehaviors>

Mapear um certificado X.509 para o símbolo que representa uma conta de usuário do Windows é considerado uma elevação de privilégio. Assim que for mapeado, o símbolo do Windows poderá ser usado para conceder acesso aos recursos protegidos. Portanto, a política de domínio exige que o certificado X.509 esteja em conformidade com sua política antes do mapeamento. O pacote de segurança SChannel impõe esse requisito.

Ao usar o .NET Framework 3.5 ou versões posteriores, o WCF garante que o certificado esteja em conformidade com a política de domínio antes de ser mapeado para uma conta do Windows.

Na primeira versão do WCF, o mapeamento é feito sem consulta à política de domínio. Portanto, é possível que aplicativos mais antigos que funcionavam ao serem executados na primeira versão falhem se o mapeamento for habilitado e o certificado X.509 não atender a política de domínio.

Confira também