Obter certificado e chave do token USB
Primeiramente deverá ser criado o projeto Java, no Eclipse ou outra IDE de sua preferência. É necessário então criar o arquivo de configuração correspondente ao dispositivo a ser usado. Foi testado com o token SERPRO ePass2000 da Feitian (distribuído pela Pronova), mas pode ser adaptado a outros dispositivos e SmartCards.
No caso desse token teremos o seguinte conteúdo do arquivo:
Linux
name=FeitianPKCS#11
library=/usr/lib/libepsng_p11.so
ou library=/usr/local/ngsrv/libepsng_p11.so.1.2.2
Windows
name=FeitianPKCS#11
library=C:\Windows\System32\ngp11v211.dll
Salvar esse arquivo com o nome de "pkcs11.cfg" na raiz do projeto Java. Ele diz ao código onde obter o driver para acessar o token (library). No caso de outros dispositivos serão definidos outras bibliotecas (.so ou .dll).
A classe abaixo serve para acessar o token:
public class TokenReader {
private X509Certificate certificate;
private KeyStore keyStore;
private PublicKey publicKey;
private PrivateKey privateKey;
public TokenReader() throws Exception {
try {
// Tenta abrir o Token padrão (ePass2000).
loadKeyStore("pkcs11.cfg");
}
catch (Exception e) {
// Não conseguiu abrir o token.
System.out.println(
"Erro ao ler o token: " + e.getMessage());
System.out.println("Providers disponíveis:");
Provider[] providers = Security.getProviders();
for (Provider provider: providers){
System.out.println(provider.getInfo());
}
throw new Exception(e);
}
}
private void loadKeyStore(String pkcs11Config)
throws KeyStoreException, FileNotFoundException {
Provider pkcs11Provider =
new SunPKCS11(new FileInputStream(pkcs11Config));
Security.addProvider(pkcs11Provider);
keyStore = KeyStore.getInstance("PKCS11", pkcs11Provider);
}
public KeyStore openKeyStore(char[] pin) throws IOException {
keyStore.load(null, pin);
privateKey =
(PrivateKey)keyStore.getKey(
keyStore.aliases().nextElement(), pin);
certificate =
(X509Certificate)keyStore.getCertificate(
keyStore.aliases().nextElement());
publicKey = certificate.getPublicKey();
return keyStore;
}
public X509Certificate getCertificate() {
return certificate;
}
public KeyStore getKeyStore() {
return keyStore;
}
public PublicKey getPublicKey() {
return publicKey;
}
public PrivateKey getPrivateKey() {
return privateKey;
}
}
Esse código utiliza o PKCS11, que é um padrão utilizado como interface para invocar operações criptográficas em hardware e utilizado para prover suporte aos tokens. É importante notar que talvez seja necessário adicionar o arquivo sunpkcs11.jar ao build path do projeto Java (ele geralmente encontra-se na pasta JAVA_HOME/lib/ext).
Caso não haja possibilidade de uso do token USB, uma opção é criar uma KeyStore através da ferramenta keytool, fornecido pelo próprio JDK.