FrameworkDemoiselle.gov.brCommunity Documentation
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");
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);
Este recurso só funciona em JVM 1.6 ou superior. Caso deseje executar em um ambiente com o Java mais antigo, desabilite a camada MSCAPI e faça o acesso diretamente pelo driver. Para saber como proceder, consulte Seção 3.9, “Desabilitar a camada de acesso SunMSCAPI” .
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.
Tabela 3.1. Drivers predefinidos para Linux
Caminho (Path) do Driver |
---|
/usr/lib/libaetpkss.so |
/usr/lib/libgpkcs11.so |
/usr/lib/libgpkcs11.so.2 |
/usr/lib/libepsng_p11.so |
/usr/lib/libepsng_p11.so.1 |
/usr/local/ngsrv/libepsng_p11.so.1 |
/usr/lib/libeTPkcs11.so |
/usr/lib/libeToken.so |
/usr/lib/libeToken.so.4 |
/usr/lib/libcmP11.so |
/usr/lib/libwdpkcs.so |
/usr/local/lib64/libwdpkcs.so |
/usr/local/lib/libwdpkcs.so |
/usr/lib/watchdata/ICP/lib/libwdpkcs_icp.so |
/usr/lib/watchdata/lib/libwdpkcs.so |
/opt/watchdata/lib64/libwdpkcs.so |
/usr/lib/libaetpkss.so.3 |
/usr/lib/libaetpkss.so.3.0 |
/usr/lib/opensc-pkcs11.so |
/usr/lib/pkcs11/opensc-pkcs11.so |
/usr/local/ngsrv/libepsng_p11.so.1.2.2 |
/usr/local/AWP/lib/libOcsCryptoki.so |
/usr/lib/libscmccid.so |
/usr/lib64/libeToken.so |
/opt/ePass2003-Castle-20141128/i386/redist/libcastle.so.1.0.0 |
/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so |
/usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.so |
/usr/lib/libneoidp11.so |
/usr/lib/x86_64-linux-gnu/pkcs11/opensc-pkcs11.so |
/usr/lib/opensc/openscpkcs11.so |
Tabela 3.2. Drivers predefinidos para windows
Caminho (Path) do Driver |
---|
WINDOWS_HOME/system32/ngp11v211.dll |
WINDOWS_HOME/system32/aetpkss1.dll |
WINDOWS_HOME/system32/gclib.dll |
WINDOWS_HOME/system32/pk2priv.dll |
WINDOWS_HOME/system32/w32pk2ig.dll |
WINDOWS_HOME/system32/eTPkcs11.dll |
WINDOWS_HOME/system32/acospkcs11.dll |
WINDOWS_HOME/system32/dkck201.dll |
WINDOWS_HOME/system32/dkck232.dll |
WINDOWS_HOME/system32/cryptoki22.dll |
WINDOWS_HOME/system32/acpkcs.dll |
WINDOWS_HOME/system32/slbck.dll |
WINDOWS_HOME/system32/cmP11.dll |
WINDOWS_HOME/system32/WDPKCS.dll |
WINDOWS_HOME/System32/Watchdata/Watchdata Brazil CSP v1.0/WDPKCS.dll |
/Arquivos de programas/Gemplus/GemSafe Libraries/BIN/gclib.dll |
/Program Files/Gemplus/GemSafe Libraries/BIN/gclib.dll |
/system32/SerproPkcs11.dll |
Tabela 3.3. Drivers predefinidos para Mac
Caminho (Path) do Driver |
---|
/usr/lib/libwdpkcs.dylib |
/usr/local/lib/libwdpkcs.dylib |
/usr/local/lib/libetpkcs11.dylib |
/usr/local/lib/libaetpkss.dylib |
//Applications//NeoID Desktop.app//Contents//Java//tools//macos//libneoidp11.dylib |
É 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.
Tabela 3.4. Configurações do PKCS#11
Ambiente | Variável de Ambiente | Variável JVM |
---|---|---|
Linux | export PKCS11_CONFIG_FILE=/usr/pkcs11/drivers.config | -DPKCS11_CONFIG_FILE=/usr/pkcs11/drivers.config |
Windows | set PKCS11_CONFIG_FILE=c:/pkcs11/drivers.config | -DPKCS11_CONFIG_FILE=c:/pkcs11/drivers.config |
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.
Tabela 3.5. Configurações do PKCS#11
Ambiente | Variável de Ambiente | Variável JVM |
---|---|---|
Linux | export PKCS11_DRIVER=/usr/lib/libepsng_p11.so | -DPKCS11_DRIVER=/usr/lib/libepsng_p11.so |
Windows | set PKCS11_DRIVER=/WINDOWS/system32/ngp11v211.dll | -DPKCS11_DRIVER=/WINDOWS/system32/ngp11v211.dll |
Linux | export PKCS11_DRIVER=Pronova::/usr/lib/libepsng_p11.so | -DPKCS11_DRIVER=Pronova::/usr/lib/libepsng_p11.so |
Windows | set PKCS11_DRIVER=Pronova::/WINDOWS/system32/ngp11v211.dll | -DPKCS11_DRIVER=Pronova::/WINDOWS/system32/ngp11v211.dll |
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.
O Sistema Operacional Windows fornece uma camada chamada MSCAPI, ou Microsoft CryptoAPI, que facilita o acesso a certificados armazenados em disco ou em dispositivos criptográficos. Neste tipo de acesso, basta que o certificado esteja corretamente instalado e válido, e a própria camada nos fornecerá o driver correto e os meios para acessar os certificados. Até a versão 5 do Java não existia um provedor de acesso para esta camada, mas na versão 6 em diante foi implementado o provedor SunMSCAPI para lidar com este tipo de acesso.
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.
Primeiro é preciso importar o certificado A1 (arquivo) no Firefox, conforme as orientações
Após feita a importação no Firefox, para viabilizar o acesso em um sistema tipo LINUX, 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 Linux:
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'"
showInfo=true
Para o Mac OS, também depois de importar no Firefox, a seguinte configuração:
name = Provedor
slot = 2
library = /Applications/Firefox.app/Contents/MacOS/libsoftokn3.dylib
nssArgs = "configdir='/Users/<usuario>/Library/Application Support/Firefox/Profiles/<nnnnnnnnn>.default'"
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.
Caso as configurações não estejam fazendo efeito, um último recurso é fechar o Firefox apagar o arquivo de profile (as configurações serão perdidas, faça backup do que for possível, antes)
Para configurar um token A3, o conteúdo do arquivo
drivers.config
deve ser especificado como mostrado abaixo.
name = Provedor
description = Token Pronova ePass2000
library = /usr/local/ngsrv/libepsng_p11.so.1.2.2
Não é possível utilizar certificados A3 e A1 no Linux ou Mac simultaneamente, devendo ser configurado somente UM dos tipos de acesso em um determinado momento.
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.
Também é possível desabilitar o MSCAPI através de uma configuração do SIGNER. Conforme mostrado a seguir:
...
import org.demoiselle.signer.core.keystore.loader.configuration.Configuration;
...
Configuration.setMSCAPI_ON(false);
...
A seguir demonstramos a configuração para o sistema Windows: