Skip to content

Integração com Blue Crystal (BluC)

crivano edited this page Jan 8, 2016 · 1 revision

Introdução

O Siga-Doc realiza assinaturas digitais através da integração um software open-source e gratuito chamado Blue Crystal - BluC.

https://github.com/bluecrystalsign

O BluC simplificou enormemente o tratamento de assinaturas digitais porque passamos a não precisar ter nenhum código ou dependências específicas para isso mais no Siga. Utilizando simples integrações via REST, pudemos resolver as seguintes situações:

  • Validar assinaturas com ou sem política da ICP-Brasil
  • Criar o pacote assinável e as assinaturas completas no padrão da ICP-Brasil
  • Assinar documentos a partir de qualquer browser (Chrome, FireFox, Edge, IE, etc)
  • Não chegamos a utlizar isso no Siga, mas também seria possível assinar documentos a partir de uma aplicação Windows qualquer, desde que ela tenha suporte a ActiveX e possa fazer chamadas HTTP

Cliente Web

HTML

O principal artefato que foi desenvolvido para essa integração é o arquivo assinatura-digital.js, e ele pode ser utilizado para facilitar a integração do BluC com qualquer outra aplicação web.

https://github.com/projeto-siga/siga/blob/vraptor-bluc/sigaex/src/main/webapp/javascript/assinatura-digital.js

Este JavaScript pressupõe a existência de alguns campos no documento HTML. Esses campos, geralmente definidos como input type="hidden", serão localizados através de seus nomes e as informações contidas ali serão utilizadas para obter os dados necessários à assinatura. Abaixo descreveremos cada campo e sua função:

  • ad_url_base: url onde se encontra o sistema que fornecerá os dados e armazenará a assinatura. Ex.: http://siga.trf2.jus.br
  • ad_url_next: url para onde deve ser feito um redirect depois que a assinatura for concluída: Ex.: /sigaex/app/expediente/doc/exibir?sigla=TRF2-MEM-2015/00001
  • ad_descr_0: código do documento a ser assinado. Ex.: TRF2-MEM-2015/00001
  • ad_url_pdf_0: url onde pode ser obtido o PDF no caso de assinatura PKCS#7 ou o pacote assinável da ICP-Brasil no caso de assinatura com política. Quando se tratar de assinatura com política, o assinatura-digital.js enviará um parâmetro adicional na query string chamado certificadoB64, contendo o certificado que será utilizado na assinatura em codificação Base64. Ex.: /sigaex/app/arquivo/exibir?arquivo=TRF2MEM201500001.pdf
  • ad_url_post_0: url que receberá um POST com os dados da assinatura para serem gravados no banco de dados. Ex.: /sigaex/app/expediente/mov/assinar_gravar
  • ad_url_post_password_0: url que recebe os dados de uma assinatura apenas com login e senha. Essa não é uma funcionalidade específica da integração com o BluC, mas pode ser usada para permitir que o sistema faça assinaturas digitais mais simples, que não necessitam de token ou smartcard. Ex.: /sigaex/app/expediente/mov/assinar_senha_gravar

Um exemplo de página web para assinar um documento pode ser visto em:

https://github.com/projeto-siga/siga/blob/vraptor-bluc/sigaex/src/main/webapp/WEB-INF/page/exMovimentacao/aAssinar.jsp

Assinatura em lote

Para assinar diversos documentos em uma única operação, basta criar campos adicionais no HTML. Os campos que finalizam com "_0" representam o primeiro documento e outros campos semelhantes podem ser criados finalizando com "_1", "_2", etc. Por exemplo, para assinar dois documentos, além dos campos apresentados anteriormente, acrescente: ad_descr_1, ad_url_pdf_1 e ad_url_post_1.

Um exemplo de página para assinar em lote pode ser visto no link abaixo. Note que essa página é um pouco mais complexa porque ela também dá ao usuário a opção de assinar com login e senha, e tudo isso é controlado por check boxes.

https://github.com/projeto-siga/siga/blob/vraptor-bluc/sigaex/src/main/webapp/WEB-INF/page/exMovimentacao/assina_tudo.jsp

A rotina de AssinarDocumentos

Além disso, a página em questão precisa ter um botão para iniciar o processo de assinatura. Esse botão deve executar o método JavaScript AssinarDocumentos(fAssinarComLoginESenha, fPolitica). Os dois parâmetros são booleanos, sendo que primeiro indica que desejamos realizar uma assinatura apenas com login e senha (ou false para assinatura com token/smartcard) e o segundo indica se deve ser usada uma política da ICP-Brasil.

Uma vez executada a rotina AssinarDocumentos, serão realizados os seguintes passos:

  1. Verificar se existe alguma assinatura digital para ser produzida com token/smartcart. Isso só tem sentido quando se tratar de assinatura em lote e o usuário puder marcar quais os documentos serão assinados. Nesse caso, é possível que a rotina AssinarDocumentos seja executada, mas que nenhum documento esteja marcado.

  2. Detectar automaticamente o componente que será utilizado para produzir as assinaturas digitais do lado do cliente. As opções são as seguintes, já em ordem de preferência: BluCRESTSigner, BluCActiveX, Java Applet CAPI, Java Applet P11.

  3. Obter o documento PDF ou o pacote assinável.

  4. Pedir o PIN quando for necessário e apenas da primeira vez quando se tratar de assinatura em lote.

  5. Realizar a assinatura propriamente dita.

  6. Enviar a assinatura para que o sistema faça a validação, monte a assinatura no padrão ICP-Brasil (se for o caso), e salve no banco de dados.

  7. Voltar para o passo 2 quando se tratar de assinatura em lote, até que todos os documentos estejam assinados.

  8. Redirecionar para a página que indica o término da assinatura.

Servidor Web

Três rotinas precisaram ser criadas na aplicação Siga-Doc para a integração com o BluC.

Validação de Assinatura

Recebe uma referência para uma assinatura digital armazenada no banco de dados e chama o Servidor BluC para fazer a validação.

Está rotina faz parte de ExMovimentacaoController.java e é chamada apenas por Ajax pelo Siga-Doc. A maior parte do código está em ExBL.java.

A chamada ao BluC REST Server foi codificada usando um cliente REST multiplataforma chamado UniREST e pode ser vista no link abaixo:

https://github.com/projeto-siga/siga/blob/vraptor-bluc/siga-ws/src/main/java/br/gov/jfrj/siga/bluc/service/BlucService.java#L120

Geração do Pacote Assinável

Recebe o certificado que será usado na assinatura digital e uma referência a um documento PDF armazenado no banco de dados, calcula o hash do documento e submete esses parâmetros ao Servidor BluC para que ele forneça o pacote assinável que será retornado. Caso não seja recebido o certificado, essa rotina retorna o PDF completo para que seja feita uma assinatura sem política.

Está rotina está definida em ExArquivoController.java do Siga-Doc da seguinte forma: aExibir(String sigla, boolean popup, String arquivo, byte[] certificado, String hash, String HASH_ALGORITHM, String certificadoB64, boolean completo, boolean semmarcas). Ela foi desenvolvida para atender a várias outras necessidades além de fornecer o pacote assinável, por isso é muito mais complexa do que o necessário para nosso entendimento do processo de assinatura digital. Ela é chamada por um POST de HTTP e o significado dos parâmetros relevantes pode ser visto abaixo:

  • sigla: referência para o documento que está recebendo a assinatura
  • certificadoB64: o Base64 do certificado que foi utilizado pelo cliente BluC para produzir a assinatura.

Além de retornar o pacote assínavel, essa rotina também insere no Header da resposta HTTP a informação de qual foi a data e hora utilizada para a criação deste pacote. Isso é importante pois o próximo método (Gravação da Assinatura) precisará dessa informação para recompor o pacote assinável.

getResponse().setHeader("Atributo-Assinavel-Data-Hora", Long.toString(dt.getTime()));

A parte mais relevante desse código pode ser vista aqui.

Gravação de Assinatura

Recebe uma assinatura digital, um certificado, a data da assinatura e uma referência ao documento em questão. Chama o Servidor BluC para completar o pacote no formato especificado pela ICP-Brasil e para validar a assinatura, depois salva no banco de dados. Caso não seja uma assinatura com política, apenas valida o PKCS#7 e salva.

A gravacão da assinatura está definida no controller do Siga-Doc da seguinte forma: aAssinarGravar(String sigla, Boolean copia, String atributoAssinavelDataHora, String assinaturaB64, String certificadoB64). Isso significa que ela recebe 5 parâmetros em um POST de HTTP. O significado de cada parâmetro pode ser visto abaixo:

  • sigla: referência para o documento que está recebendo a assinatura
  • copia: informa se a assinatura representa uma assinatura mesmo (false) ou uma autenticação ou conferência de cópia com o original (true)
  • atributoAssinavelDataHora: data e hora da assinatura digital. Necessário para recompor o pacote assinável que é parte da assinatura completa no padrão ICP-Brasil. Essa data e hora deve ser exatamente igual a data e hora que foi fornecida no momento da criação do pacote assinável.
  • assinaturaB64: a assinatura digial que foi produzida pelo BluCRESTSigner ou outro cliente do BluC. Este campo é um byte array codificado em Base64.
  • certificadoB64: o Base64 do certificado que foi utilizado pelo cliente BluC para produzir a assinatura.

A maior parte do código que processa a assinatura está no método assinarDocumento de ExBL.java, que pode ser visto aqui.

Integrando o BluC com uma aplicação desktop

Embora este recurso não seja utilizado no Siga-Doc, a integração com uma aplicação Windows seria também bastante simples.

Basta utilizar o BluC ActiveX, para realizar as operações de assinatura digital exatamente da mesma forma que é feito nesse trecho do assinatura-digital.js, só em que outra linguagem como C#, VB.NET ou Delphi.

As chamadas para o servidor do BluC podem ser realizadas através de REST, ou SOAP, o que for mais conveniente em relação à linguagem escolhida.

Outros Recursos

Antes do desenvolvimento dos componentes REST, tanto o signer quanto o server, chegamos a produzir uma apresentação das funcionalidades de assinatura digital. Esse material está desatualizado, mas pode servir para ilustrar alguns detalhes mais gerais sobre o processo. Caso haja interesse a apresentação pode ser visualizada em:

https://docs.google.com/presentation/d/1JlxWhcsQvk7MjdLrbuFNO73pIAyHmuWBgZCW5_tguRE/edit?usp=sharing

Clone this wiki locally