[RESOLVIDO]Atualizando certificado: unable to find valid certification path to requested target

Bom dia pessoal,

Sou 100% newbie em certificados digitais (embora até conheço o comando keytool e sua utilização básica) e, aqui no trabalho me passaram um projeto para atualizar o certificado utilizado por uma aplicação já existente.

Essa aplicação hoje já está em produção, e funciona perfeitamente. Foi feita em Java 1.6.23 e roda num Tomcat 6.

Olhando a estrutura dessa aplicação já existente, vi que ela utiliza dois arquivos:

[b] - truststore.jks

  • nome_da_empresa.pfx[/b]

E, nos fontes, ocorre a configuração das propriedades da seguinte forma:

System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
System.setProperty("javax.net.ssl.keyStore", "/nome_da_empresa.pfx");
System.setProperty("javax.net.ssl.keyStorePassword", "senha");

...

System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", "/truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "senha");

Como mencionei, a aplicação hoje funciona corretamente, porém, o certificado vence em 1 semana. Por isso, para renovar o certificado, me enviaram dois arquivos:

nome_da_empresa.cer: Novo certificado
nome_da_empresa.key: Chave privada com senha

Ou seja, eu preciso atualizar a aplicação existente, estando de posse desses dois arquivos listados acima.

Bom, eu sei que consigo importar o arquivo .cer para o truststore do Java usando um comando tipo:

keytool -import -alias aliasqualquer -file nome_da_empresa.cer -keystore truststore.jks

Mas, aí entra minha dúvida, e parte da qual não consigo sair:

  1. Eu não deveria importar o certificado junto com a chave privada? Tipo, o comando keytool que listei antes não serviria, pois importei somente o certificado (arquivo .cer), quando deveria passar também o arquivo que contem a chave privada. Eu vi que o keytool tem o parâmetro “importkeystore”, mas, não estou sabendo utilizar (os exemplos que eu encontrei pelo Google não utilizam o arquivo .cer, o que me leva a crer que estou fazendo algo errado, rs).

  2. Como eu gero (ou atualizo) o outro arquivo que a aplicação utiliza, com a extensão .pfx?

Edit -------

Ok, to lendo agora nesse site da Microsoft, parece que este arquivo PFX é o arquivo com as chaves pública e privada. Pelo que estou entendo, no meu cenário seria este arquivo nome_da_empresa.key (ao menos pela descrição que me foi passada). Eu devo então importar o .cer com o keytool (exatamente como coloquei antes) e usar esse “nome_da_empresa.key” no lugar do pfx? Em todo caso, fiz desse jeito e enviei para homologar (tem uma restrição de segurança que proíbe testar pela minha máquina), assim que tiver retorno coloco aqui o que deu.

Edit 2 -----

Mudei o título do tópico, para condizer com o erro que tenho agora.

Muito obrigada.

ESTOU TENTANDO CANCELAR UMA NOTA FISCAL ELETRÔNICA EMITIDA PELO SISTEMA GRATUITO DE MEISSÃO DE NOTA FISCAL ELETRÔNICA. E RECEBI A MESAGEM DE ERRO QUE SEGUE ABAIXO, ALGUÉM PODE ME AJUDAR???

null
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at br.gov.sp.fazenda.dsge.view.util.DSGEViewControllerHelper.getControllerFromView(DSGEViewControllerHelper.java:73)
at br.gov.sp.fazenda.dsen.view.SelecionarCertificadoGUI.bindController(SelecionarCertificadoGUI.java:330)
at br.gov.sp.fazenda.dsen.view.SelecionarCertificadoGUI.a(SelecionarCertificadoGUI.java:61)
at br.gov.sp.fazenda.dsen.view.SelecionarCertificadoGUI.(SelecionarCertificadoGUI.java:47)
at br.gov.sp.fazenda.dsen.view.SelecionarCertificadoGUI.a(SelecionarCertificadoGUI.java:246)
at br.gov.sp.fazenda.dsen.view.SelecionarCertificadoGUI.getCertificado(SelecionarCertificadoGUI.java:283)
at br.gov.sp.fazenda.dsen.controller.CancelarNotaFiscalNaoCadastradaController.a(CancelarNotaFiscalNaoCadastradaController.java:53)
at br.gov.sp.fazenda.dsen.controller.CancelarNotaFiscalNaoCadastradaController.actionPerformed(CancelarNotaFiscalNaoCadastradaController.java:35)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.Dialog$1.run(Unknown Source)
at java.awt.Dialog$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.awt.Dialog.show(Unknown Source)
at java.awt.Component.show(Unknown Source)
at java.awt.Component.setVisible(Unknown Source)
at java.awt.Window.setVisible(Unknown Source)
at java.awt.Dialog.setVisible(Unknown Source)
at br.gov.sp.fazenda.dsen.view.DSENMenuBuilder$10.actionPerformed(DSENMenuBuilder.java:218)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at de.muntjak.tinylookandfeel.TinyMenuItemUI.doClick(TinyMenuItemUI.java:534)
at de.muntjak.tinylookandfeel.TinyMenuItemUI$MouseInputHandler.mouseReleased(TinyMenuItemUI.java:421)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: sun/security/pkcs11/wrapper/PKCS11Exception
at br.gov.sp.fazenda.dsen.model.business.CertificadoBusiness.pesquisarCertificadosIE(CertificadoBusiness.java:360)
at br.gov.sp.fazenda.dsen.model.business.CertificadoBusiness$$EnhancerByCGLIB$$abbb417e.CGLIB$pesquisarCertificadosIE$7()
at br.gov.sp.fazenda.dsen.model.business.CertificadoBusiness$$EnhancerByCGLIB$$abbb417e$$FastClassByCGLIB$$91814590.invoke()
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:167)
at br.gov.sp.fazenda.dsge.model.dao.util.DSGEDAOInterceptorHelper.intercept(DSGEDAOInterceptorHelper.java:66)
at br.gov.sp.fazenda.dsen.model.business.CertificadoBusiness$$EnhancerByCGLIB$$abbb417e.pesquisarCertificadosIE()
at br.gov.sp.fazenda.dsen.model.facade.SistemaFacade.pesquisarCertificadosIE(SistemaFacade.java:227)
at br.gov.sp.fazenda.dsen.controller.SelecionarCertificadoController.b(SelecionarCertificadoController.java:72)
at br.gov.sp.fazenda.dsen.controller.SelecionarCertificadoController.a(SelecionarCertificadoController.java:60)
at br.gov.sp.fazenda.dsen.controller.SelecionarCertificadoController.(SelecionarCertificadoController.java:48)
… 69 more
Caused by: java.lang.ClassNotFoundException: sun.security.pkcs11.wrapper.PKCS11Exception
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
… 79 more

Bem, eu procedi como disse anteriormente, e testei utilizando este arquivo com a chave privada no lugar do arquivo PFX. Infelizmente, não deu certo. Ocorre o erro abaixo ao tentar estabelecer uma comunicação:

Caused by: java.io.IOException: toDerInputStream rejects tag type 45
	at sun.security.util.DerValue.toDerInputStream(DerValue.java:806)
	at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1201)
	at java.security.KeyStore.load(KeyStore.java:1185)
	at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.getDefaultKeyManager(DefaultSSLContextImpl.java:150)
	at com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl.<init>(DefaultSSLContextImpl.java:40)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:355)
	at java.lang.Class.newInstance(Class.java:308)
	at java.security.Provider$Service.newInstance(Provider.java:1221)
	... 46 more

Bem, mas, algo que esqueci de fazer antes: eu abri o arquivo “.key” com o Notepad+, e, o conteúdo dele é tipo:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,1ECCA0E0DA60DE8A

dados encriptados

-----END RSA PRIVATE KEY-----

Ou seja, é uma chave no formato PEM. Já a extensão “.cer” é para certificados tipo DER, e, se for isso, eu tenho uma incompatibilidade aqui, correto? Eu preciso que o certificado seja PEM (ou que o formato da chave seja alterado, sei lá qual é mais fácil). Ao menos, é o que estou entendo.

Alguém conhece melhor essas extensões?

Obrigada.

Nota: Rangel6, seu problema não parece muito relacionado ao meu. Sugiro abrir outro tópico, mas, dando mais detalhes sobre o seu problema, e, de preferência, em letras minúsculas :wink:

Nossa, tá dando trabalho isso, caramba!

Bem, eu mudei o título do tópico, porque, o erro agora é outro.

A solução para o cenário que eu estava tendo: esse arquivo PFX é o que contém a chave pública e a privada, e eu preciso disso para efetuar a comunicação com o web service. Assim, solicitei ao suporte para gerar um pfx para mim (sei que você faz isso através do openssl, mas, aqui no trabs só tenho Windows, e não quis mexer com isso). Deste modo, eles me enviaram o arquivo PFX, de modo que agora já tenho:

certificado.cer: arquivo com o certificado digital e a chave pública;
certificado.pxf: arquivo com as duas chaves;

Feito isso, eu comecei o processo todo do zero de novo. Gerei uma nova keystore:

keytool -import -alias mykey -file certificado.cer -keystore truststore.jks

Adicionado sem problemas. Cliquei duas vezes no certificado.cer, para fazer a importação dele e depois fiz a importação no cacerts. Se eu mando listá-lo, vejo lá a entrada (dentre várias outras):

keytool -keystore JAVA_HOME\jre\lib\security\cacerts -v -list

[code]Alias name: mykey
Creation date: Jun 20, 2012
Entry type: trustedCertEntry

Owner: CN=ws.pbh.gov.br, OU=Equipamento A1, OU=CONTRIBUINTE, OU=Autoridade Certificadora SERPROACF, O=ICP-Brasil, C=BR
Issuer: CN=Autoridade Certificadora do SERPRO Final v3, OU=CSPB-1, OU=Servico Federal de Processamento de Dados - SERPRO, O=ICP-Brasil, C=BR
Serial number: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Valid from: Wed Jun 13 17:16:37 BRT 2012 until: Thu Jun 13 17:12:01 BRT 2013
Certificate fingerprints:
MD5: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
SHA1: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Signature algorithm name: SHA256withRSA
Version: 3[/code]

O problema é, quando vou acessar o serviço, ocorre o erro:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318) ... 50 more

Eu entenderia perfeitamente esse erro… se o alias já não estivesse no meu cacerts! :frowning:

Esqueci algum passo?

Para quem passar por algo semelhante: no meu caso, o arquivo PXF foi gerado com erro (alguma falha na cadeia de certificados). Pedi para o setor responsável gerar novamente, e só substitui na minha aplicação e funcionou.