Conceitos básicos sobre validação da assinatura XML

Adobe AIR 1.5 e posterior

Veja uma explicação rápida e exemplos de códigos para a validação de assinaturas de XML nos seguintes artigos de início rápido do Adobe Developer Connection:

O Adobe® AIR® fornece a classe XMLSignatureValidator e a interface IURIDreferencer para validar assinaturas XML. A sintaxe XML aceita pela classe XMLSignatureValidator é um subconjunto das recomendações do W3C para processamento e sintaxe de assinatura XML. (Como somente um subconjunto da recomendação tem suporte, nem todas as assinaturas permitidas podem ser validadas). O AIR não fornece uma API para a criação de assinaturas XML.

Classes de validação da assinatura XML

A API de validação da assinatura XML inclui estas classes:

Pacote

Classes

flash.security

Constantes de string de XMLSignatureValidator são definidas nas seguintes classes:

flash.events

Uso das classes de validação da assinatura XML

Para usar a classe XMLSignatureValidator para validar uma assinatura XML, você deve:

  • Criar um objeto XMLSignatureValidator

  • Fornecer uma implementação da interface IURIDereferencer. O objeto XMLSignatureValidator chama o método dereference() de IURIDereferencer, enviando a URI para cada referência em uma assinatura. O método dereference() deve resolver a URI e retornar os dados referenciados (que devem estar no mesmo documento como a assinatura, ou podem estar em um recurso externo).

  • Defina as configurações de confiança do certificado, verificação de revogação e validação de referência do objeto XMLSignatureValidator conforme apropriado para o seu aplicativo.

  • Adicione ouvintes do evento para os eventos complete e error .

  • Chame o método verify , enviando a assinatura para verificação.

  • Manipule os eventos complete e error e interprete os resultados.

O exemplo a seguir implementa uma função validate() que verifica a validade de uma assinatura XML. As propriedades de XMLSignatureValidator são definidas de forma que o certificado de assinatura deve ficar na armazenagem confiável do sistema, ou encadeado a ela. O exemplo também supõe que uma classe IURIDereferencer adequada denominada XMLDereferencer exista.

private function validate( xmlSignature:XML ):void 
{ 
    var verifier:XMLSignatureValidator = new XMLSignatureValidator(); 
    verifier.addEventListener(Event.COMPLETE, verificationComplete); 
    verifier.addEventListener(ErrorEvent.ERROR, verificationError); 
    try 
    { 
        verifier.uriDereferencer = new XMLDereferencer(); 
 
        verifier.referencesValidationSetting = 
            ReferencesValidationSetting.VALID_IDENTITY; 
        verifier.revocationCheckSetting = RevocationCheckSettings.BEST_EFFORT; 
        verifier.useSystemTrustStore = true; 
         
        //Verify the signature 
        verifier.verify( xmlSignature ); 
    } 
    catch (e:Error) 
        { 
            trace("Verification error.\n" + e); 
        } 
} 
 
//Trace verification results 
private function verificationComplete(event:Event):void 
 
    var signature:XMLSignatureValidator = event.target as XMLSignatureValidator; 
    trace("Signature status: " + signature.validityStatus + "\n"); 
    trace("  Digest status: " + signature.digestStatus + "\n"); 
    trace("  Identity status: " + signature.identityStatus + "\n"); 
    trace("  Reference status: " + signature.referencesStatus + "\n"); 
} 
 
private function verificationError(event:ErrorEvent):void 
{ 
    trace("Verification error.\n" + event.text);                 
}

O processo de validação da assinatura XML

Quando você chama o método verify() de XMLSignatureValidator, o AIR executa estas etapas:

  • O tempo de execução verifica a integridade criptográfica da assinatura usando a chave pública do certificado de assinatura.

  • O tempo de execução estabelece a integridade criptográfica, a identidade e a confiabilidade do certificado com base nas configurações atuais do objeto XMLSignatureValidator.

    A confiança inserida no certificado de assinatura é a chave para a integridade do processo de validação. A validação da assinatura é conduzida com um processo criptográfico bem definido, mas a confiabilidade do certificado de assinatura é um julgamento que não pode ser realizado de forma algorítmica.

    Em geral, há três formas de decidir se um certificado é confiável:

    • Confiando em autoridades de certificação e no armazenamento confiável do sistema operacional.

    • Obtendo, diretamente de quem assina, uma cópia do certificado, outro certificado que sirva como âncora confiável do certificado ou informações suficientes para identificar confiavelmente o certificado, como a chave pública.

    • Perguntando ao usuário final do aplicativo se ele confia no certificado. Tal pergunta é inválida com certificados autoassinados, pois as informações de identificação no certificado não são confiáveis por inerência.

  • O tempo de execução verifica a integridade criptográfica dos dados assinados.

    Os dados assinados são verificados com a ajuda da implementação do seu IURIDereferencer. Para cada referência no documento de assinatura, o método dereference() de implementação do IURIDereferencer é chamado. Os dados retornados pelo método dereference() são usados para computar a compilação de referência. Esse valor de compilação é comparado à compilação registrada no documento de assinatura. Se a compilação for correspondente, os dados ainda não foram alterados desde a assinatura.

    Uma consideração importante ao contar com os resultados de validação de assinatura XML é que apenas o que é assinado é seguro. Por exemplo, considere um manifesto assinado listando os arquivos de um pacote. Quando o XMLSignatureValidator verifica a assinatura, ele verifica somente se o manifesto não foi alterado. Os dados dos arquivos não são assinados, portanto a assinatura ainda será válida quando arquivos referenciados no manifesto forem alterados ou excluídos.

    Nota: Para verificar arquivos em tal manifesto, você pode computar a compilação dos dados do arquivo (usando o mesmo algoritmo de hash usado no manifesto) e comparar o resultado com a compilação armazenada no manifesto assinado. Em alguns casos, e necessário verificar também a presença de arquivos adicionais.

Interpretação dos resultados de validação

Os resultados de validação são relatados pelas propriedades de status do objeto XMLSignatureValidator. Essas propriedades podem ser lidas depois que o objeto validador despacha o evento complete . As quatro propriedades de status incluem: validityStatus , digestStatus , identityStatus e referencesStatus .

A propriedade validityStatus

A propriedade validityStatus relata a validade geral da assinatura. A validityStatus depende do estado de outras três propriedades de status e pode ter um destes valores:

  • valid — Se digestStatus , identityStatus e referencesStatus forem todas válidas .

  • invalid — Se uma ou mais propriedades de status individuais forem inválidas .

  • unknown — se uma ou mais propriedades de status individual forem desconhecidas e nenhum status individual for inválido .

A propriedade digestStatus

A propriedade digestStatus relata os resultados da verificação criptográfica da compilação da mensagem. Esta propriedade digestStatus pode ter um dos seguintes valores:

  • valid — Se o documento de assinatura se mantiver sem alterações desde que a assinatura tenha sido realizada.

  • invalid — se o documento de assinatura foi alterado ou foi malformado.

  • unknown — Se o método verify() não tiver sido concluído sem erros.

A propriedade identityStatus

A propriedade identityStatus relata o status do certificado de assinatura. O valor dessa propriedade depende de vários fatores, incluindo:

  • a integridade criptográfica do certificado

  • se o certificado foi expirado ou revogado

  • se o certificado é confiável na máquina atual

  • o estado do objeto XMLSignatureValidator (como se outros certificados foram adicionados para criar a cadeia confiável, se esses certificados são confiáveis e os valores das propriedades useSystemTrustStore e revocationCheckSettings )

A propriedade identityStatus pode ter estes valores:
  • valid — Para ser considerado válido, o certificado de assinatura deve atender estas condições:

    • O certificado de assinatura deve estar inalterado.

    • O certificado de assinatura não deve ter expirado ou sido revogado, exceto quando um carimbo de data/hora válido estiver presente na assinatura. Se a assinatura tiver um carimbo de data/hora, o certificado será considerado válido, desde que estivesse válido no momento da assinatura do documento. (O certificado usado pelo serviço de carimbo de data/hora para assinar o carimbo de data/hora deve se vincular a um certificado de raiz confiável no computador do usuário).

    • O certificado de assinatura é confiável. Um certificado é confiável se estiver na armazenagem confiável do sistema ou encadeado com outro certificado na armazenagem confiável do sistema e se você definir a propriedade useSystemTrustStore como true. Você também pode designar um certificado como confiável usando o método addCertificate() do objeto XMLSignatureValidator.

    • O certificado é, na realidade, o certificado de assinatura.

  • invalid — O certificado está expirado ou revogado e nenhum carimbo de data e hora fornecendo validade de horário da assinatura está presente, ou o certificado foi alterado.

  • unknown — Se o certificado não for inválido, mas não for confiável. Certificados autoassinados, por exemplo, serão reportados como unknown (a menos que explicitamente confiáveis). O identityStatus também é reportado como unknown se o método verify() não tiver sido concluído sem erros ou se a identidade não tiver sido verificada porque a compilação de assinatura é inválida.

A propriedade referencesStatus

A propriedade referencesStatus reporta a integridade criptográfica das referências no elemento SignedData da assinatura.

  • valid — Se a compilação computada de cada referência na assinatura corresponder à compilação registrada na assinatura XML. Um status valid indica que os dados assinados não foram alterados.

  • invalid — Se qualquer compilação computada não corresponder à compilação da assinatura.

  • unknown — Se as compilações de referência não tiverem sido verificadas. As referências não são verificadas se a compilação geral da assinatura for invalid ou o certificado de assinatura for inválido. Se identityStatus for unknown , então as referências serão verificadas somente quando referencesValidationSetting for validOrUnknown .