CXF + Autenticação Mútua (Mutual Auth) [RESOLVIDO]

Boa tarde,

Estou tentando utilizar o CXF para acessar um Web Service que está configurado para utilizar Autenticação mútua.
Mas não entendo o porque ele não está conseguindo capturar meu certificado.

Segue o fonte abaixo:

		System.setProperty("javax.net.debug", "all");
		System.setProperty("java.security.debug", "all");
		String keystore = new File(Thread.currentThread().getContextClassLoader().getResource(".jks").toURI()).getAbsolutePath();
		KeyStore ks = getKeyStore("JKS", keystore, "senha");
		KeyManager[] kmgrs = getKeyManagers(ks, "senha");
		TrustManager[] tmgrs = getTrustManagers(ks);
		
		TLSClientParameters tlsClientParameters = new TLSClientParameters();
		tlsClientParameters.setSecureSocketProtocol("SSL");
		tlsClientParameters.setKeyManagers(kmgrs);
		tlsClientParameters.setTrustManagers(tmgrs);
		
		URL wsdl = Thread.currentThread().getContextClassLoader().getResource("servico.wsdl");
		Servico servico = new Servico(wsdl);
		ServicoSoap soap = servico.getServicoSoap12();
		
		Client client = ClientProxy.getClient(soap);
		HTTPConduit http = (HTTPConduit) client.getConduit();
		
		HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
		
		http.setClient(httpClientPolicy);
		http.setTlsClientParameters(tlsClientParameters);
		
		String retorno = soap.executar(parametro1, parametro2);
		System.out.println(retorno);

Gerou o seguinte erro:

org.apache.cxf.interceptor.Fault: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:95)
	at org.apache.cxf.interceptor.BareOutInterceptor.handleMessage(BareOutInterceptor.java:68)
	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:221)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:296)
	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:242)
	at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:178)
	at $Proxy38.executar(Unknown Source)
	at HTTPSTest.testSSLMutual(HTTPSTest.java:289)
	at HTTPSTest.main(HTTPSTest.java:231)
Caused by: com.ctc.wstx.exc.WstxIOException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:313)
	at org.apache.cxf.interceptor.AbstractOutDatabindingInterceptor.writeParts(AbstractOutDatabindingInterceptor.java:93)
	... 9 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1591)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:975)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:123)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:405)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:832)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1803)
	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1765)
	at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:42)
	at com.ctc.wstx.io.UTF8Writer.flush(UTF8Writer.java:96)
	at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:214)
	at com.ctc.wstx.sw.BaseStreamWriter.flush(BaseStreamWriter.java:311)
	... 10 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:285)
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:191)
	at sun.security.validator.Validator.validate(Validator.java:218)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:954)
	... 27 more
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:280)
	... 33 more

Alguém saberia me dizer o que eu fiz de errado?

Ats,
Endrigo Antonini

Bom, continuei pesquisando e encontrei meu problema.
Meu fonte estava correto o que eu estava precisando era registrar o certificado do servidor no Java. Lembre-se no Java, não basta apenas cadastrar o certificado no SO, isso fará com que os navegadores WEB não reclamem em relação a ele, mas a cadeia certificadora precisa ser cadastrada no Java.

Abaixo o link do passo a passo para fazer esse cadastramento.
http://blogs.sun.com/andreas/entry/no_more_unable_to_find

Ats,
Endrigo Antonini

Olá

Legal que colocou a solução aqui.

Obrigado

[]s
Luca

E será que alguem já fez isso ai pra me falar como se faz?

Eu vi o exemplo, mas, tá em english e é pra chapeu-vermelho…

Eu importei o certificado que exportei da lista de certificados… Um da “VeriSign, Inc.”, mas, ainda não tive exito…
Fiquei com o mesmo erro. [único detalhe é que não uso CFX]

proteus_adi, Qual a sua dúvida? Como “cadastrar” os certificados no Java?
Ou como fazer a conexão SSL Mutual Auth

Ats,
Endrigo Antonini

Bem,
Hoje creio que meu problema seja ssl com autenticação mútua…

O erro :[quote]AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
[/quote] aparece de maneira similar à sua antes…

Eu registrei o meu certificado no keyStore e tambem um certificado da “VeriSign, Inc” que exportei do keyStore do windows.

Detalhe é que eu NÃO uso cxf [ e nem consegui usar ].
O código é esse http://www.guj.com.br/posts/list/101258.java descrito no final;

Aceito qualquer ajuda ou oração…

Bom,

Pelo que eu to vendo é o seguinte… você esta tendo problema com o SSL mutual (essa foi fácil, você falou… rss) e não conseguiu seguir os passos do site que passei.

Então vamos ver se consigo te ajudar.

Copie o fonte da URL: http://blogs.sun.com/andreas/resource/InstallCert.java

e execute da seguinte forma:

java InstallCert <domínio>

exemplo:

java InstallCert ecc.fedora.redhat.com

Fazendo isso ele irá gerar um arquivo JKS em algum diretório (seria legal mexer no fonte pra ver onde ele está criando) com toda a cadeia certificadora desse domínio.

Outra coisa interessante a se fazer e ir no site da Sun e baixar o JCE Unlimeted, isso irá ajudar bastante.

Avisa ae se conseguiu.

Ats,
Endrigo Antonini

Outra coisa que acabei de lembrar, é bom você adicionar a cadeia certificadora do teu certificado dentro de teu JKS. Agora não lembro direito como faz isso, mas da pra “Googlar” isso e é bem provavel que você encontre.

Isso é necessário porque o certificado que você está usando é gerado “abaixo” do ICP Brasil, certo? mas no meio existem outras entidades envolvidas.

Ats,
Endrigo Antonini

Auauaa,

Boum…
Eu não sei se tou lá no meu dia de sorte…
Pra rodar eu precisei mudar o “InputStream in = new FileInputStream(file);” pra um “FileInputStream in = new FileInputStream(file);” [Parte do InstallCert]

E fiz a chamada…

try { InstallCert.main(new String[] { "hnfe.fazenda.mg.gov.br","123456" }); } catch (Exception e) { e.printStackTrace(); }

E a resposta…

[quote]javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target[/quote] aparece pra assustar… rs**

Dai ele me mostrou uma lista de 4 certificados…
Por via das dúvidas… botei logo os 4…

Dai, ele salvou…

Mudei as linhas de properties pra [code]
System.setProperty(“javax.net.ssl.trustStoreType”, “PKIX”);
System.setProperty(“javax.net.ssl.trustStore”,
“D:\dev\java\UPGER\UPGER\jssecacerts”);
System.setProperty(“javax.net.ssl.trustStorePassword”, “123456”);

        System.setProperty("javax.net.ssl.keyStoreType", "jks");
        System.setProperty("javax.net.ssl.keyStore", 
                           "C:\\JAVA\\JDEV\\jdevstudio10132\\jdk\\jre\\lib\\security\\keystore.jks");
        System.setProperty("javax.net.ssl.keyStorePassword", "123456");[/code]

E tive uma resposta nova:

[quote]AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.net.SocketException: Default SSL context init failed: PKIX not found
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:java.net.SocketException: Default SSL context init failed: PKIX not found[/quote]

E agora?! PKIX é o certificado deles, correto? O meu está em JKS, certo? [incluí no keystore.jks via keytool]
Será que tou enviando o certificado errado?
Algum parâmetro adicional?

Tá… vamos detalhar um pouco mais então…

Instalou o JCE Unlimited?

Você vai rodar esse fonte ali… Coloque apenas o domínio para rodar… e não a URL toda… ele irá gerar uma mensagem de output dizendo os certificados que está importando.
No seu fonte de SSL, não mude nada, continue referenciado para seu jks que contem seu certificado digital e sua chave pública. se mesmo assim dar erro, é necessário você procurar no Google dae como se faz para importar para o JKS a “Cadeia Certificadora”, isso quer dizer, você comprou o certificado de uma entidade, que esta registrada em outra que está em outra e asssim por diante. Essa informação também é muito necessária para que o Servidor da outra ponta veja seu certificado e diga que ele é válido.

Outra coisa, seu certificado foi gerado por uma AC (Autoridade Certificadora) válida? ou é um gerado através de programas? Lembre-se que para aceitarem seu certificado ele deve ter sido gerado por uma AC cadastrada no ICP Brasil, caso contrário você não tem como garantir que seu certificado é válido.

Ats,
Endrigo Antonini

Estou evoluindo, penso… [risada]

Bom…
Consegui uma mensagem do tipo :

[quote]faultString: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure[/quote]

Acho que isso quer dizer que o servidor recusou meu certificado, confere?
Seria isso mesmo?

Eu tenho um certificado bonitão. A1 da Caixa “AC CertSign” ‘num sei das quanta’.
Boum…
Eu exportei meu certificado do repositório do windows no formato pfx, e no formato cer; [Um com a particular outra sem].
Eu consigo usar a pfx pra assinaturas, mas, não consegui importa-la via keytool. Dai importei a cer.

Que guerra…
=],

São essas emoções que fazem com que nosso trabalho nunca caia na rotina…
rs**

Hehehehe… verdade… e bota emossão…

Cara… existe uma ferramenta chamada Portecle que gera um único JKS contendo a chave pública e privada.

Quanto ao erro, se eu não me engano ele recusou seu certificado, porque deu erro no processo de handshake que é o processo da “troca de certificados” na conexão SSL Mutual Auth.

E em relação ao JCE? conseguiu instalar?

Vou ver se lembro aqui como fiz para colocar a minha cadeia certificadora dentro do JKS.

O que uso é assim: tenho um JKS que tem minha chave pública, chave privada, e certificados da minha cadeia certificadora. Com todas essas informações consigo ter acesso a Sefaz sem problemas algum.

Tenta esses passos:
Baixa aquela feramenta:

  • Cria um novo JKS
  • Importa os certificados (Publico e Privado)
  • Altera aquele fonte que te passei, para gerar a cadeia certificadora dentro desse teu JKS.

Tenta isso e me diz se deu certo, se eu não me engano foi assim que fiz… faz tanto tempo que não lembro.

Ats,
Endrigo Antonini

Nossa Senhora APARECIDA abençoa esse moleque e o google…

Minha chave importada apartir de um cer tava dando erro mesmo…

Baixei o aplicativo : http://yellowcat1.free.fr/keytool_iui.html e, seguindo sua dica, gerei uma nova keystore…

[quote]<?xml version="1.0" encoding="UTF-8"?>

2
1.07
107
Servico em operacao
31
2008-08-28T15:43:15
3
[/quote]

Aleluia Aleluia…


Repassando os passos pra quem não tiver afim de ler tanta coisa

  1. Rodar o InstallCert e importar os certificados do servidor [da receita estadual, no meu caso] : trustStore;
  2. Recriar a keystore com o aplicativo acima : keyStore
  3. Correr pro abraço…

hehehe

Agora começa a etapa Delphi do meu projeto, penso… ou não, né,
Agora que consegui colocar a keyStore no repositório, acho que vou mudar a parte da assinatura pra pegar da keystore… pra ficar bonitinho… padronizado…

Obrigado pela ajuda com os certificados…

NFe parte 2, A missão…

Hehehehehe…

De nada cara… já me bati muitoo com essa coisa de Assinatura Digital e SSL com Autenticação Mútual por causa do projeto NF-e…

Mas me responde uma coisa por curiosidade… parte Delphi? Como assim? Seu ERP é em Delphi?

Ats,
Endrigo Antonini

Sim…

Um sistema ENORME [ como todo ERP costuma ser] e pesado feito um elefante… Em delphi com modificações até no VCL do delphi. N Camadas dom DCom…

Dai, simplesmente agente precisa da tal NFe, e, o danadinho do delphi num faz essas coisas com facilidade…
Não que seja facil fazer em Java, claro… Mas é um ambiente feito pra isso…

Projetos Desktop são TODOS Delphi… Web são oracle[webtool kit] ou java;

JNI, pensei na hora…
Menor impacto na arquitetura desse elefante…
Menos problemas a tratar…

Bom…
Essa foi minha aposta…

abs
Wellingthon Araújo

Proteus_adi, segui teus passos, juntamente com as dicas do amigo que te ajudou.
Tudo certo com a importacao dos certificados.
No meu caso que uso A3, nao posso importar a minha Pk para um JKS. Mas isso nao
importa, visto o sistema estar acessando certinho o token.

O problema que me retorna e’ 403 Forbidden.
Passou por isso? Ou alguem da lista?

Grato pela atencao.

é…
nesse caso, o passo 3 [correr pro abraço] que é o mais importante… não acontece…

Vejamos…

  1. Importar os certificados é importante…
  2. Enviar o certificado também…

O envio do seu certificado está ok?

[quote=proteus_adi]

  1. Importar os certificados é importante…
  2. Enviar o certificado também…

O envio do seu certificado está ok?[/quote]

Bem, ai a resposta fica dificil :slight_smile:
Uso um A3. Como saber se meu certificado esta sendo enviado corretamente?
Consigo acessar a site com ele normal (?wsdl, por exemplo).

Alguma dica de verificacao?

Grato pela atencao

:frowning:

O meu é A1,

e suspeito que o código abaixo é responsável pela mágica da autenticação

[code] System.setProperty(“java.protocol.handler.pkgs”,
“com.sun.net.ssl.internal.www.protocol”);
System.setProperty(“javax.net.ssl.trustStoreType”, “jks”);
System.setProperty(“javax.net.ssl.trustStore”, trustStore);
System.setProperty(“javax.net.ssl.trustStorePassword”, pin);

        System.setProperty("javax.net.ssl.keyStoreType", "jks");
        System.setProperty("javax.net.ssl.keyStore", keyStore);
        System.setProperty("javax.net.ssl.keyStorePassword", pin);[/code]

onde keyStore é o caminho da minha keyStore…

Sendo assim… casos diferentes imagino…

Conta ai pagente como é que tá a parte de envio da requisição…
=]

Li em outro post que somente de um IP cadastrado os servicos podem ser acessados.
Isto confere? Se sim, deve ser este o problema de 403 Forbidden. Estou na minha software house e nao no cliente contribuinte.

Alencar