-
Notifications
You must be signed in to change notification settings - Fork 96
Integração com Blue Crystal (BluC)
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
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.
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:
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.
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:
-
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.
-
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.
-
Obter o documento PDF ou o pacote assinável.
-
Pedir o PIN quando for necessário e apenas da primeira vez quando se tratar de assinatura em lote.
-
Realizar a assinatura propriamente dita.
-
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.
-
Voltar para o passo 2 quando se tratar de assinatura em lote, até que todos os documentos estejam assinados.
-
Redirecionar para a página que indica o término da assinatura.
Três rotinas precisaram ser criadas na aplicação Siga-Doc para a integração com o BluC.
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:
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.
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.
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.
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