Partilhar via


Assinaturas Authenticode com carimbo de data/hora

As assinaturas do Microsoft Authenticode fornecem garantias de autoria e integridade para dados binários. O carimbo de data/hora do Authenticode é baseado em contra-assinaturas PKCS #7 padrão. As ferramentas de assinatura da Microsoft permitem que os desenvolvedores afixem carimbos de data/hora ao mesmo tempo em que afixam assinaturas Authenticode. O carimbo de data/hora permite que as assinaturas do Authenticode sejam verificáveis mesmo após a expiração dos certificados usados para assinatura.

Uma breve introdução ao Authenticode

A Authenticode aplica tecnologia de assinatura digital para garantir a autoria e a integridade de dados binários, como software instalável. Um navegador da Web do cliente ou outros componentes do sistema podem usar as assinaturas do Authenticode para verificar a integridade dos dados quando o software é baixado ou instalado. As assinaturas Authenticode podem ser usadas com muitos formatos de software, incluindo .cab, .exe, .ocx e .dll.

A Microsoft mantém uma lista de autoridades de certificação públicas (CAs). Os emissores de certificados Authenticode atualmente incluem SSL.com, Digicert, Sectigo (Comodo) e GlobalSign.

Sobre o carimbo de data/hora criptográfico

No passado, uma variedade de métodos criptográficos de carimbo de data/hora foi proposta. Veja, por exemplo, Haber e Stornetta "How to Time-Stamp a Digital Document" no Journal of Cryptology (1991) e Benaloh e de Mare "One-Way Accumulators: A Decentralized Alternative to Digital Signatures" em Springer-Verlag Lecture Notes in Computer Science vol. 765 (EUROCRYPT '93). Um resumo estendido deste artigo está disponível na Microsoft Research. (Esses recursos podem não estar disponíveis em alguns idiomas, países ou regiões.) Como o tempo é uma quantidade física, e não matemática, esses métodos geralmente dizem respeito a como vincular objetos para que sua ordem de criação possa ser determinada ou como agrupar eficientemente objetos que podem ser descritos como tendo sido criados simultaneamente.

Os sistemas que pretendem autenticar o tempo como uma quantidade sempre exigem alguma forma de confiança. Em um ambiente fortemente contraditório, protocolos complexos podem ser usados para garantir algum grau de sincronia. No entanto, esses protocolos exigem ampla interação entre as partes afetadas. Na prática, se alguém só precisa de certificação de tempo de uma fonte confiável, a fonte pode simplesmente atuar como um notário, fornecendo uma declaração assinada (certificação) de que o objeto foi apresentado para assinatura no horário indicado.

O método de contra-assinatura de carimbo de data/hora implementado abaixo permite que as assinaturas sejam verificadas mesmo após o certificado de assinatura ter expirado ou sido revogado. O carimbo de data/hora permite que o verificador saiba de forma confiável a hora em que a assinatura foi afixada e, assim, confie na assinatura se ela era válida naquele momento. O carimbo de data/hora deve ter uma fonte de tempo confiável e protegida.

PKCS #7 Documentos Assinados e Contra-assinaturas

PKCS #7 é um formato padrão para dados criptográficos, incluindo dados assinados, certificados e listas de revogação de certificados (CRLs). O tipo específico de interesse PKCS #7 no contexto do carimbo de data/hora são signed data, correspondendo ao tipo de conteúdo SignedData definido pelo PKCS #7.

O pacote PKCS #7 consiste em SignedData que identifica o conteúdo real e determinadas informações sobre ele e blocos de assinatura SignerInfo. Um SignerInfo pode conter uma contra-assinatura, que recursivamente é outro SignerInfo. Em princípio, uma sequência de tais contra-assinaturas pode estar presente. A contra-assinatura é um atributo não autenticado em relação à assinatura no SignerInfo; ou seja, pode ser aposto após a assinatura original. Em forma de esboço:

SignedData (PKCS #7)

  • Versão (do PKCS #7, geralmente versão 1)
  • DigestAlgorithms (coleção de todos os algoritmos usados pelos blocos de assinatura SignerInfo, para processamento otimizado)
  • ContentInfo (contentType é igual a SignedData, mais conteúdo ou referência ao conteúdo)
  • Certificados OPCIONAIS (coleção de todos os certificados usados)
  • CRLs OPCIONAIS (coleção de todas as CRLs)
  • Blocos de assinatura SignerInfo (a assinatura real, composta por um ou mais blocos de assinatura SignerInfo)

SignerInfo (o bloco de assinatura)

  • Versão (do PKCS #7, geralmente versão 1)
  • Certificado (emissor e número de série para identificar exclusivamente o certificado do signatário em SignedData)
  • DigestAlgorithm mais o DigestEncryptionAlgorithm mais o Digest (hash), mais o EncryptedDigest (assinatura real)
  • OPTIONAL AuthenticatedAttributes (por exemplo, assinado por este signatário)
  • OPTIONAL UnauthenticatedAttributes (por exemplo, não assinado por este signatário)

Um exemplo de um atributo autenticado é a hora de assinatura (OID 1.2.840.113549.1.9.5) porque faz parte do que o serviço de carimbo de data/hora assina. Um exemplo de um atributo não autenticado é a contra-assinatura (OID 1.2.840.113549.1.9.6) porque ele pode ser afixado após a assinatura. Nesse caso, o próprio SignerInfo contém um SignerInfo (a Contra-assinatura).

Observação

O objeto assinado na contra-assinatura é a assinatura original (ou seja, o EncryptedDigest do SignerInfo original).

 

SignTool e o processo Authenticode

O SignTool está disponível para assinatura Authenticode e dados binários de carimbo de data/hora. A ferramenta é instalada na pasta \Bin do caminho de instalação do SDK (Software Development Kit) do Microsoft Windows.

A assinatura e o carimbo de data/hora de dados binários são relativamente simples usando o SignTool. O editor deve obter um certificado de assinatura de código de uma autoridade de certificação de assinatura de código comercial. Por conveniência, a Microsoft publica e atualiza uma lista de CAs públicas, incluindo aquelas que emitem certificados Authenticode. Quando estiverem prontos para publicação, os arquivos de objeto serão assinados e marcados com data e hora usando os parâmetros de linha de comando apropriados com a ferramenta SignTool. O resultado de qualquer operação SignTool é sempre um SignedData no formato PKCS #7.

O SignTool aceita como entrada dados binários brutos a serem assinados e marcados com data e hora, ou dados binários assinados anteriormente a serem marcados com data e hora. Os dados que foram assinados anteriormente podem ser marcados com carimbo de data/hora usando o comando signtool timestamp.

Argument Descrição
/t HTTPAddress Indica que o arquivo deve ser carimbado com data e hora. Deve ser fornecido um URL que especifique um endereço de um servidor de carimbo de data/hora. /t pode ser usado com os comandos signtool sign e signtool timestamp.

 

Para obter mais informações sobre ferramentas que podem ser úteis nesse contexto, consulte Ferramentas de criptografia e SignTool.

Detalhes da implementação e formato da transmissão

O SignTool depende da implementação do Windows Authenticode para criar assinaturas de carimbo de data/hora. O Authenticode opera em arquivos binários, por exemplo, .cab, .exe, .dll ou .ocx. O Authenticode primeiro cria a assinatura, produzindo um PKCS #7 SignedData. É esse SignedData que deve ser contra-assinado, conforme descrito em PKCS #9.

O processo de contra-assinatura ocorre em quatro etapas:

  1. Copie a assinatura (ou seja, o encryptedDigest) do SignerInfo do PKCS #7 SignedData.
  2. Construa uma solicitação de carimbo de data/hora cujo conteúdo seja a assinatura original. Envie isso para o servidor de carimbo de data/hora ASN.1 (Abstract Syntax Notation One) codificado como TimeStampRequest.
  3. Receba um carimbo de data/hora, formatado como um segundo PKCS #7 SignedData, retornado do servidor de carimbo de data/hora.
  4. Copie o SignerInfo do carimbo de data/hora diretamente para o PKCS #7 SignedData original, como uma contra-assinatura PKCS #9 (ou seja, um atributo não autenticado no SignerInfo do original).

Solicitação de carimbo de data/hora

A solicitação de carimbo de data/hora é enviada em uma mensagem HTTP 1.1 POST. No cabeçalho HTTP, a diretiva CacheControl é definida como no-cache e a diretiva Content-Type é definida como application/octet-stream. O corpo da mensagem HTTP é uma codificação base64 da codificação DER (Distinguished Encoding Rules) da solicitação de carimbo de data/hora.

Embora não seja usada atualmente, a diretiva Content-Length também deve ser usada na construção da mensagem HTTP, pois ajuda o servidor de carimbo de data/hora a localizar onde a solicitação está no HTTP POST.

Outros cabeçalhos HTTP também podem estar presentes e devem ser ignorados se não forem compreendidos pelo solicitante ou pelo servidor de carimbo de data/hora.

A solicitação de carimbo de data/hora é uma mensagem codificada em ASN.1. O formato da solicitação é o seguinte.

TimeStampRequest ::= SEQUENCE {
   countersignatureType OBJECT IDENTIFIER,
   attributes Attributes OPTIONAL, 
   content  ContentInfo
}

O countersignatureType é o identificador de objeto (OID) que o identifica como uma contra-assinatura de carimbo de data/hora e deve ser o OID exato 1.3.6.1.4.1.311.3.2.1.

Nenhum atributo está incluído atualmente na solicitação de carimbo de data/hora.

O conteúdo é um ContentInfo, conforme definido pelo PKCS #7. O conteúdo são os dados a serem assinados. Para carimbo de data/hora de assinatura, o ContentType deve ser Data e o conteúdo deve ser o encryptedDigest (assinatura) do SignerInfo do conteúdo PKCS #7 a ser carimbado com carimbo de data/hora.

Resposta de carimbo de data/hora

A resposta do carimbo de data/hora também é enviada em uma mensagem HTTP 1.1. No cabeçalho HTTP, a diretiva Content-Type também é definida como application/octet-stream. O corpo da mensagem HTTP é uma codificação base64 da codificação DER da resposta do carimbo de data/hora.

A resposta do carimbo de data/hora é uma mensagem assinada PKCS #7 assinada pelo carimbador de tempo. O ContentInfo da mensagem PKCS #7 é idêntico ao ContentInfo recebido no carimbo de data/hora. O conteúdo PKCS #7 contém o atributo autenticado por hora de assinatura (definido em PKCS #99, OID 1.2.840.113549.9.5).

Depois que o Authenticode recebe o carimbo de data/hora do servidor, o Authenticode incorpora o carimbo de data/hora no PKCS #7 SignedData original como uma contra-assinatura. Para fazer isso, o ContentInfo do PKCS #7 SignedData é descartado e o SignerInfo do carimbo de data/hora retornado é copiado como uma contra-assinatura para o SignerInfo do PKCS #7 SignedData original. A cadeia de certificados do carimbo de data/hora também é copiada em Certificados no PKCS #7 SignedData original como um atributo não autenticado do signatário original.