Exemplo de segurança de descoberta

A especificação Discovery não exige que os pontos de extremidade que participam do processo de descoberta sejam seguros. Melhorar as mensagens de descoberta com segurança atenua vários tipos de ataques (alteração de mensagens, negação de serviço, replay, spoofing).

O exemplo DiscoveryScenario implementa canais personalizados que calculam e verificam assinaturas de mensagens usando o formato de assinatura compacto (descrito na Seção 8.2 da especificação WS-Discovery). O exemplo suporta a especificação 2005 Discovery e a versão 1.1.

O canal personalizado é aplicado sobre a pilha de canais existente para pontos de extremidade de descoberta e anúncio. Desta forma, um cabeçalho de assinatura é aplicado para cada mensagem enviada. A assinatura é verificada nas mensagens recebidas e quando não corresponde ou quando as mensagens não têm assinatura, as mensagens são descartadas. Para assinar e verificar mensagens, o exemplo usa certificados.

Debate

WCF é extensível e permite aos usuários a possibilidade de personalizar canais como desejado. O exemplo implementa um elemento de vinculação segura de descoberta que cria canais seguros. Os canais seguros aplicam e verificam assinaturas de mensagens e são aplicados sobre a pilha atual.

O elemento de vinculação segura cria fábricas de canais e ouvintes de canal seguros.

Fábrica de canais seguros

A fábrica de canais seguros cria canais de saída ou duplex que adicionam uma assinatura compacta aos cabeçalhos das mensagens. Para manter as mensagens tão pequenas quanto possível, é utilizado o formato de assinatura compacta. A estrutura de uma assinatura compacta é mostrada no exemplo a seguir.

<d:Security ... >
  [<d:Sig Scheme="xs:anyURI"
         [KeyId="xs:base64Binary"]?
          Refs="..."
         [PrefixList]="xs:NMTOKENS"
          Sig="xs:base64Binary"
          ... />]?
  ...
</d:Security>

Nota

O PrefixList foi adicionado no protocolo da versão Discovery de 2008.

Para calcular a assinatura, o exemplo determina os itens de assinatura expandidos. Uma assinatura XML (SignedInfo) é criada, usando o prefixo do ds namespace, conforme exigido pela especificação WS-Discovery. O corpo e todos os cabeçalhos em namespaces de descoberta e endereçamento são referenciados na assinatura, portanto, não podem ser adulterados. Cada elemento referenciado é transformado usando a Canonicalização Exclusiva (http://www.w3.org/2001/10/xml-exc-c14n#) e, em seguida, um valor de digestão SHA-1 é calculado (http://www.w3.org/2000/09/xmldsig#sha1). Com base em todos os elementos referenciados e seus valores digest, o valor da assinatura é calculado usando o algoritmo RSA (http://www.w3.org/2000/09/xmldsig#rsa-sha1).

As mensagens são assinadas com um certificado especificado pelo cliente. O local da loja, o nome e o nome do assunto do certificado devem ser especificados quando o elemento de vinculação é criado. A KeyId assinatura compacta representa o identificador de chave do token de assinatura e é o Identificador de Chave de Assunto (SKI) do token de assinatura ou (se o SKI não existir) um hash SHA-1 da chave pública do token de assinatura.

Ouvinte de Canal Seguro

O ouvinte de canal seguro cria canais de entrada ou duplex que verificam a assinatura compacta nas mensagens recebidas. Para verificar a assinatura, o KeyId especificado na assinatura compacta anexada à mensagem é usado para selecionar um certificado do armazenamento especificado. Se a mensagem não tiver uma assinatura ou a verificação de assinatura falhar, as mensagens serão descartadas. Para usar a associação segura, o exemplo define uma fábrica que cria um elemento de vinculação seguro personalizado UdpDiscoveryEndpoint e UdpAnnouncementEndpoint com a descoberta adicionada. Esses pontos de extremidade seguros podem ser usados em ouvintes de anúncios de descoberta e serviços detetáveis.

Detalhes da amostra

O exemplo inclui uma biblioteca e 4 aplicativos de console:

  • DiscoverySecurityChannels: uma biblioteca que expõe a ligação segura. A biblioteca calcula e verifica a assinatura compacta para mensagens de saída/entrada.

  • Serviço: Um serviço que expõe o contrato ICalculatorService, auto-hospedado. O serviço está marcado como Detetável. O usuário especifica os detalhes do certificado usado para assinar mensagens especificando o local e o nome do armazenamento e o nome do assunto ou outro identificador exclusivo para o certificado, e o armazenamento onde os certificados de cliente estão localizados (os certificados usados para verificar a assinatura de mensagens de entrada). Com base nesses detalhes, um UdpDiscoveryEndpoint com segurança adicional é criado e usado.

  • Client: Esta classe tenta descobrir um ICalculatorService e chamar métodos no serviço. Novamente, um UdpDiscoveryEndpoint com segurança adicional é construído e usado para assinar e verificar as mensagens.

  • AnnouncementListener: um serviço auto-hospedado que escuta anúncios on-line e off-line e usa o ponto de extremidade de anúncio seguro.

Nota

Se Setup.bat for executado várias vezes, o gerenciador de certificados solicitará que você escolha um certificado para adicionar, pois há certificados duplicados. Nesse caso, Setup.bat deve ser abortado e Cleanup.bat deve ser chamado, porque as duplicatas já foram criadas. Cleanup.bat também solicita que você escolha um certificado a ser excluído. Selecione um certificado na lista e continue executando Cleanup.bat até que nenhum certificado seja restante.

Para usar este exemplo

  1. Execute o script Setup.bat a partir de um prompt de comando do desenvolvedor para Visual Studio. O exemplo usa certificados para assinar e verificar mensagens. O script cria os certificados usando Makecert.exe e, em seguida, instala-os usando Certmgr.exe. O script deve ser executado com privilégios de administrador.

  2. Para criar e executar o exemplo, abra o arquivo Security.sln no Visual Studio e escolha Reconstruir tudo. Atualize as propriedades da solução para iniciar vários projetos: selecione Iniciar para todos os projetos, exceto DiscoverySecureChannels. Execute a solução normalmente.

  3. Depois de concluir o exemplo, execute o script Cleanup.bat que remove os certificados criados para este exemplo.