FrameworkDemoiselle.gov.brCommunity Documentation

Capítulo 3. Funcionalidades relativas ao Keystore

3.1. Introdução
3.2. Carregamento de KeyStore PKCS#12
3.3. Carregamento de KeyStore PKCS#11 em ambiente Linux
3.4. Carregamento de KeyStore PKCS#11 em ambiente Windows
3.5. Lista de Drivers
3.6. Configuração de Token / SmartCard em tempo de execução
3.7. Configuração de Token / SmartCard por variáveis de ambiente
3.8. Configuração de Token / SmartCard por arquivo de configurações
3.8.1. Utilizando certificados armazenados em Disco ou em Token / SmartCard no Windows
3.8.2. Utilizando certificados armazenados em Disco no Linux ou Mac
3.8.3. Utilizando certificados armazenados em Token / SmartCard no Linux ou Mac
3.9. Desabilitar a camada de acesso SunMSCAPI

A RSA Laboratories definiu algumas especificações de uso de criptografia e assinatura digital conhecidas pelo prefixo PKCS. Duas delas estão relacionadas ao tipo de keystore (chaveiro) que é o recipiente que armazena um par de chaves criptográficas. São elas PKCS#11 e PKCS#12.

PKCS#11 define uma API genérica para acesso a hardware criptográfico, comumente chamados de Token (pendrive) ou Smartcard (cartão e leitora).

PKCS#12 define um formato de arquivo digital usado para guardar chaves privadas acompanhadas de seus certificados digitais.

A linguagem Java suporta a utilização desses formatos e com isso define o que chamamos de KeyStore. Um KeyStore é usado para armazenar um ou mais certificados digitais e também o par de chaves, com isso é possível utilizar os padrões da RSA através da mesma interface. A partir de um objeto KeyStore instanciado é possível navegar pelos certificados digitais contidos no KeyStore por meio dos apelidos (alias) destes certificados.

O componente Demoiselle-Signer visa facilitar o uso destes KeyStores, seja PKCS#11 ou PKCS#12. A maneira como se carrega um KeyStore do tipo PKCS#11, que é um dispositivo em hardware, difere quando trabalhamos com sistemas operacionais diferentes e, em alguns casos,até mesmo versões de JVM.

No ambiente Windows, é possível utilizar a API padrão do sistema operacional de carregamento de KeyStore PKCS#11, chamada MSCAPI que controla os certificados instalados de uma forma mais genérica, mas para isso precisamos também saber a versão da JVM instalada. Isso é necessário porque na versão 1.6 a implementação JCE já comporta o tratamento nativo na plataforma e na versão 1.5 ou inferior é necessário utilizar uma biblioteca para trabalhar com a API nativa do Windows.

Em ambiente Unix-like é possível carregar um KeyStore PKCS#11 a partir de um driver específico, mas é preciso saber o fabricante e o caminho do driver no sistema operacional.

Para carregamento de KeyStore formato PKCS#12, ou seja, em arquivo, o processo de carregamento é o mesmo para os diversos sistemas operacionais.

As funcionalidades do componente estão acessíveis por meio da fábrica org.demoiselle.signer.core.keystore.loader.factory.KeyStoreLoaderFactory de objetos do tipo org.demoiselle.signer.core.keystore.loader.KeyStoreLoader.

O uso da fábrica é importante, mas não é obrigatório. A importância dela se deve à funcionalidade de descobrir qual a melhor implementação para o carregamento de KeyStore baseando-se em configurações. Utilizando a fábrica não é necessário escrever códigos específicos para um determinado sistema operacional, pois a fábrica identifica qual o sistema operacional e a versão da JVM para fabricar a melhor implementação.

Exemplo de uso da fábrica de objetos KeyStoreLoader

KeyStoreLoader keyStoreLoader = KeyStoreLoaderFactory.factoryKeyStoreLoader();

Exemplo de uso da fábrica de objetos KeyStoreLoader para KeyStore PKCS#12

KeyStoreLoader keyStoreLoader = KeyStoreLoaderFactory.factoryKeyStoreLoader(new File("/usr/keystore.p12"));

Para carregar um KeyStore a partir de uma arquivo no formato PKCS#12 basta utilizar a classe org.demoiselle.signer.core.keystore.loader.implementation.FileSystemKeyStoreLoader.

Abaixo temos exemplos de uso.

KeyStore keyStore = (new FileSystemKeyStoreLoader(new File("/usr/keystore.p12"))).getKeyStore("password");
KeyStore keyStore = KeyStoreLoaderFactory.factoryKeyStoreLoader(new File("/usr/keystore.p12")).getKeyStore("password");

Para carregar um KeyStore PKCS#11 basta utilizar a classe org.demoiselle.signer.core.keystore.loader.implementation.DriverKeyStoreLoader

Para configuração de drivers favor acessar a área de Configuração do componente em Seção 3.5, “Lista de Drivers”.

Abaixo temos exemplos de uso.

KeyStore keyStore = (new DriverKeyStoreLoader()).getKeyStore("PIN NUMBER");
KeyStore keyStore = KeyStoreLoaderFactory.factoryKeyStoreLoader().getKeyStore("PIN NUMBER");

Caso se queira instanciar um KeyStore a partir de um driver específico que não esteja na lista de driver configurada, é possível informar o driver como parâmetro para a classe, veja o exemplo:

KeyStore keyStore = (new DriverKeyStoreLoader()).getKeyStore("PIN NUMBER", "Pronova", "/usr/lib/libepsng_p11.so");
KeyStore keyStore = (new DriverKeyStoreLoader()).getKeyStore("PIN NUMBER", "/usr/lib/libepsng_p11.so");

Importante

Este código também funciona em ambiente Windows, bastando especificar o driver correto a ser utilizado.

Para carregar um KeyStore utilizando a API nativa do Windows basta utilizar a classe br.gov.frameworkdemoiselle.certificate.keystore.loader.implementation.MSKeyStoreLoader.

Abaixo temos exemplos de uso.

KeyStore keyStore = (new MSKeyStoreLoader()).getKeyStore(null);
KeyStore keyStore = KeyStoreLoaderFactory.factoryKeyStoreLoader().getKeyStore(null);

Uma das configurações mais importantes desse componente é a lista de drivers PKCS#11 e seus respectivos arquivos. O componente já possui uma lista pré-estabelecida conforme a tabela a seguir.




É possível, porém, adicionar mais drivers em tempo de execução. Para isso é necessário trabalhar com a classe org.demoiselle.signer.core.keystore.loader.configuration.Configuration.

Configuration.getInstance().addDriver("Nome do Driver", "Path do Driver");

Este código irá procurar pelo driver e caso ele exista, ou seja, o path do arquivo for válido, o driver será colocado a disposição para futuro uso pelas implementações de carregamento de KeyStore.

Caso seja necessário verificar os drivers já informados, podemos usar a seguinte construção:

Map<String, String> drivers = Configuration.getInstance().getDrivers();

Em algumas ocasiões pode ser inviável utilizar o Configuration para adicionar um driver diretamente no código. Neste caso, A API do Java permite definir um arquivo de configuração onde pode-se informar o nome do driver e seus parâmetros. O componente permite a definição desse arquivo por meio de váriáveis de ambiente ou variáveis da JVM.

Abaixo temos o exemplo de como declarar essas configurações.


A estrutura deste arquivo pode ser encontrada aqui para Java 1.5, aqui para Java 1.6 ou aqui para Java 1.7.

Uma alternativa a este arquivo de configuração é informar o driver diretamente. Para isso basta informar na variável, conforme o exemplo abaixo.


Quando a variável for declarada através da JVM, ela deve ser feita diretamente no painel de controle do JAVA. A seguir demonstramos a configuração para o sistema Windows.

Abra o painel de controle e seleciona e abra o aplicativo "Java".


Selecione a aba "Java" e clique em "View..."


Na aba "User", em "Runtime Parameters", coloque a declaração da variável. Em seguida, aplique as alterações.


As configurações acima demonstram uma configuração mais refinada para o carregamento de certificados em dispositivos, mas o componente possui um procedimento padrão a ser executado caso se deseje um método mais simplificado. A seguir é explicado como utilizar este mecanismo.

Ao Contrario do Windows, que utiliza a API da MS-CAPI para abstrair o acesso aos certificados digitais, em outros sistemas operacionais este recurso não existe. Para efetuar o acesso, precisamos criar um arquivo de configuração informando os parâmetros de acesso.

Para viabilizar o acesso em um sistema Não-Windows, deve ser criado um arquivo chamado drivers.config dentro do diretório [/home/usuario] com a parametrização mostrada abaixo. Nesta configuração serão carregados todos os certificados A1 que estejam instalados no Firefox.

Para o Ubuntu:



name = Provedor
slot = 2
# para 64 bits
library = /usr/lib/x86_64-linux-gnu/nss/libsoftokn3.so
# para 32 bits
# library = /usr/lib/nss/libsoftokn3.so
nssArgs = "configdir='/home/<usuario>/.mozilla/firefox/<nnnnnnnn>.default' certPrefix='' keyPrefix='' secmod='secmod.db'  flags='readWrite'"
showInfo=true            

Para o Mac OS:



name = Provedor
slot = 2
library = /Applications/Firefox.app/Contents/MacOS/libsoftokn3.dylib
nssArgs = "configdir='/Users/<usuario>/Library/Application Support/Firefox/Profiles/<nnnnnnnnn>.default' certPrefix='' keyPrefix='' secmod='secmod.db' flags='readOnly'"

Importante

A sequência de caracteres que precede o .default , como em nnnnnnnn.default é criptografada e, sendo assim, é diferente para cada equipamento e cada usuário.

Quando o componente é utilizado em ambiente Windows, o acesso é feito através de uma camada de abstração chamada MSCAPI, que abstrai informações que são particulares de cada token ou smartcard, como os drivers do dispositivo, por exemplo. Este tipo de recurso facilita o uso do componente com dispositivos de diversos fabricantes. Porém, podem existir casos específicos em que o acesso precisa ser feito diretamente ao driver para utilização de funções específicas, como forçar o logout de um token. Para isso, é necessário informar na JVM um parâmetro chamado mscapi.disabled passando o valor true . Este parâmetro informa que o acesso será feito via PKCS11, sendo necessário informar o arquivo de configuração do token que se deseja acessar. Caso o parâmetro mscapi.disabled esteja ausente, o componente fará uso do MSCAPI normalmente.

A seguir demonstramos a configuração para o sistema Windows.