Este artigo é para desenvolvedores que precisam trabalhar com:
1. Conexão a webservices protegidos por cadeias de certificados digitais.
2. Controlar cadeias de certificados durante um processamento.
3. Trabalhar com tokens PKCS11.
4. Trabalhar com certificados PKCS12 fornecidos por orgãos como SERASA (E-CPF, E-CNPJ).
Antes de começar.
Para realizar os procedimentos deste artigo é necessário fazer o download do pacote Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy do site da sun, com este pacote podemos trabalhar com certificados do tipo PKCS12, PKCS11.
Existe também uma ferramenta para importar/exportar certificados, criar keystores e assinar arquivos, que serão muito úteis para os testes que serão feitos durante o desenvolvimento do seu software e até mesmo criar seus próprios certificados para seus clientes se um certificado raiz não for necessário.
Código.
package com.softsimples.crypto;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.PublicKey;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class GerenciadorDeKeystore {
private static final String PKCS11 = "PKCS11";
private final KeyStore keyStore;
private final char[] pwdKeystoreCliente;
private final File arquivoKeystoreCliente;
private String aliasKeystoreCliente;
private final String tipoKeystoreCliente;
private final File arquivoKeystoreServidor;
private final char[] pwdKeystoreServidor;
private final String tipoKeystoreServidor;
public GerenciadorDeKeystore(String tipoKeystoreCliente, File arquivoKeysotreCliente, String aliasKeystoreCliente,
char[] pwdKeystoreCliente, String tipoKeystoreServidor, File arquivoKeystoreServidor,
char[] pwdKeystoreServidor) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
this.tipoKeystoreCliente = tipoKeystoreCliente;
this.arquivoKeystoreCliente = arquivoKeysotreCliente;
this.aliasKeystoreCliente = aliasKeystoreCliente;
this.pwdKeystoreCliente = pwdKeystoreCliente;
this.tipoKeystoreServidor = tipoKeystoreServidor;
this.arquivoKeystoreServidor = arquivoKeystoreServidor;
this.pwdKeystoreServidor = pwdKeystoreServidor;
this.keyStore = carregarKeystore(this.tipoKeystoreCliente, this.pwdKeystoreCliente, this.arquivoKeystoreCliente);
}
private KeyStore carregarKeystore(String type, char[] pwd, File arquivo) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
KeyStore store = null;
if (type.equalsIgnoreCase(PKCS11)) {
Provider p = new sun.security.pkcs11.SunPKCS11("pkcs11.cfg");
Security.addProvider(p);
store = KeyStore.getInstance(type);
store.load(null, pwd);
this.aliasKeystoreCliente = store.aliases().nextElement();
} else {
store = KeyStore.getInstance(type);
store.load(new FileInputStream(arquivo), pwd);
}
return store;
}
public X509Certificate getCertificado() throws KeyStoreException {
return (X509Certificate)this.keyStore.getCertificate(this.aliasKeystoreCliente);
}
public PrivateKey getPrivateKey() throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException {
Key key = this.keyStore.getKey(this.aliasKeystoreCliente, pwdKeystoreCliente);
return (key instanceof PrivateKey) ? (PrivateKey)key : null;
}
public PublicKey getPublicKey() throws KeyStoreException {
Certificate certificate = this.getCertificado();
return certificate.getPublicKey();
}
public void configurarConexaoSegura() {
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
System.setProperty("javax.net.ssl.trustStoreType", this.tipoKeystoreServidor);
System.setProperty("javax.net.ssl.trustStore", this.arquivoKeystoreServidor.getAbsolutePath());
System.setProperty("javax.net.ssl.trustStorePassword", String.valueOf(this.pwdKeystoreServidor));
if (tipoKeystoreCliente.equalsIgnoreCase(PKCS11)) {
System.setProperty("javax.net.ssl.keyStore", "NONE");
System.setProperty("javax.net.ssl.keyStoreType", this.tipoKeystoreCliente);
System.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-NFe");
System.setProperty("javax.net.ssl.keyStoreAlias", this.aliasKeystoreCliente);
System.setProperty("javax.net.ssl.keyStorePassword", String.valueOf(this.pwdKeystoreCliente));
} else {
System.setProperty("javax.net.ssl.keyStoreType", this.tipoKeystoreCliente);
System.setProperty("javax.net.ssl.keyStore", this.arquivoKeystoreCliente.getAbsolutePath());
System.setProperty("javax.net.ssl.keyStorePassword", String.valueOf(this.pwdKeystoreCliente));
}
}
}