Emissão NF-e + Tomcat

33 respostas
jeroqueiroz

Alguem utiliza Tomcat em sua aplicação par emissão de NF-e?

Ou utiliza aplicação Web para emissão? Qual server usa?

33 Respostas

jeroqueiroz

Alguém?

jeroqueiroz

Alguém utiliza?

cinei

Estou com Tomcat.

jeroqueiroz

cinei,

Desde já muito obrigado pela resposta.

Você poderia mim ajudar sobre a questão da estrutura, pq estou tendo alguns erros que não sei o q pode ser e não sei mais o q fazer…

O Mais interessante é que quando rodo a classe através do Java Application ele roda, porém quando é através da aplicação Web não vai.

Poderia mim descrever a estrutura do seu projeto? Ambiente?

Desde já agradeço.

cinei

Qual seria seu problema: para gerar, assinar enviar ou obter a resposta?
Outra coisa: o fato de estar rodando no Tomcat, não influencia.

jeroqueiroz

Meu problema esta no envio, sendo que ele assina normal. Porém como falei quando utilizo a mesma classe executando através do método main rodando Run As -> Java Application ela roda normal e obter o retorno correto.

Qundo utilizo o Tomcat 7 estou tendo o problema abaixo:

Linha do código onde o erro esta sendo apresentado.

Erro apresentado no console.

3 ["http-bio-8080"-exec-3] INFO http.HTTPSender  - Unable to sendViaPost to url[https://hnfe.sefaz.ba.gov.br/webservices/nfenw/NfeRecepcao2.asmx]
javax.net.ssl.SSLHandshakeException: Error signing certificate verify
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
	at java.io.BufferedInputStream.fill(Unknown Source)
	at java.io.BufferedInputStream.read(Unknown Source)
	at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
	at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
	at org.apache.commons.httpclient.HttpConnection.readLine(HttpConnection.java:1116)
	at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.readLine(MultiThreadedHttpConnectionManager.java:1413)
	at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1973)
	at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1735)
	at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1098)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
	at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:560)
	at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:199)
	at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:76)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:400)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:225)
	at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:438)
	at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:402)
	at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
	at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
	at br.inf.portalfiscal.www.nfe.wsdl.nferecepcao2.NfeRecepcao2Stub.nfeRecepcaoLote2(NfeRecepcao2Stub.java:196)
	at br.gov.fazenda.nfe.www.envio.NFeRecepcaoCerA3.NfeRecepcaoLoteA3(NFeRecepcaoCerA3.java:98)
	at br.gov.fazenda.nfe.www.inicial.EmissaoPadraoNfe.emiteNotaFiscal(EmissaoPadraoNfe.java:28)
	at br.gov.fazenda.nfe.www.inicial.NfeEnvio.doGet(NfeEnvio.java:34)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:403)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:301)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:162)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:140)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.security.InvalidKeyException: Unsupported key type: SunPKCS11-SmartCard RSA private key, 1024 bits (id 1, token object, sensitive, unextractable)
	at sun.security.mscapi.RSACipher.engineGetKeySize(RSACipher.java:345)
	at javax.crypto.Cipher.b(DashoA13*..)
	at javax.crypto.Cipher.a(DashoA13*..)
	at javax.crypto.Cipher.init(DashoA13*..)
	at java.security.Signature$CipherAdapter.engineInitSign(Unknown Source)
	at java.security.Signature$Delegate.init(Unknown Source)
	at java.security.Signature$Delegate.chooseProvider(Unknown Source)
	at java.security.Signature$Delegate.engineInitSign(Unknown Source)
	at java.security.Signature.initSign(Unknown Source)
	at com.sun.net.ssl.internal.ssl.RSASignature.engineInitSign(Unknown Source)
	at java.security.Signature$Delegate.engineInitSign(Unknown Source)
	at java.security.Signature.initSign(Unknown Source)
	at com.sun.net.ssl.internal.ssl.HandshakeMessage$CertificateVerify.<init>(Unknown Source)

Mudei o server para o Jboss 5.0, a mensagem de erro mudou:

cinei

Utilizo Tomcat 6.29.

Verifique se o endereço do webservice está correto.
ESte endereço está meio estranho: hnfe.sefaz.ba.gov.br/webservices/nfenw/NfeRecepcao2.asmx

jeroqueiroz

Vou voltar a versão para o Tomcat 6.

Quando ao endereço estou passando os seguintes:

Bahia

RS

A minha maior dúvida e que não mudo absolutamente nada, é ela roda normal na execução Java Application.

Obtém o retorno na SEFAZ “Lote recebido com sucesso”.

Agradeço a atenção. Poderia descrever a classe que envia o arquivo?

Minha Classe:

NfeRecepcao2Stub.NfeDadosMsg dadosMsg = new NfeRecepcao2Stub.NfeDadosMsg();
            dadosMsg.setExtraElement(ome);
            NfeRecepcao2Stub.NfeCabecMsg nfeCabecMsg = new NfeRecepcao2Stub.NfeCabecMsg();
            
            //Código do Estado.
            nfeCabecMsg.setCUF(codigoDoEstado);
            
            //Versao do XML
            nfeCabecMsg.setVersaoDados("2.00");

            NfeRecepcao2Stub.NfeCabecMsgE nfeCabecMsgE = new NfeRecepcao2Stub.NfeCabecMsgE();
            nfeCabecMsgE.setNfeCabecMsg(nfeCabecMsg);

            NfeRecepcao2Stub stub = new NfeRecepcao2Stub(url.toString());
            NfeRecepcao2Stub.NfeRecepcaoLote2Result result = stub.nfeRecepcaoLote2(dadosMsg, nfeCabecMsgE);
            
            retornoSolicitacao.add(0, NfeConstantes.MsgResposta.SUCESSO);

Sendo que esta é a linha que apresenta o erro:

Você utiliza o Axis2 na sua aplicação?

Utiliza Netbeans ou Eclipse?

Mais uma vez agradeço.

jeroqueiroz

Mudei o server para o Tomcat 6. Continua o erro:

24/07/2011 17:44:47 org.apache.axis2.transport.http.HTTPSender sendViaPost
INFO: Unable to sendViaPost to url[https://hnfe.sefaz.ba.gov.br/webservices/nfenw/NfeRecepcao2.asmx]
javax.net.ssl.SSLHandshakeException: Error signing certificate verify
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverHelloDone(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
	at java.io.BufferedInputStream.fill(Unknown Source)
	at java.io.BufferedInputStream.read(Unknown Source)
	at org.apache.commons.httpclient.HttpParser.readRawLine(HttpParser.java:78)
	at org.apache.commons.httpclient.HttpParser.readLine(HttpParser.java:106)
	at org.apache.commons.httpclient.HttpConnection.readLine(HttpConnection.java:1116)
	at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.readLine(MultiThreadedHttpConnectionManager.java:1413)
	at org.apache.commons.httpclient.HttpMethodBase.readStatusLine(HttpMethodBase.java:1973)
	at org.apache.commons.httpclient.HttpMethodBase.readResponse(HttpMethodBase.java:1735)
	at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1098)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
	at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:560)
	at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:199)
	at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:76)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:400)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:225)
	at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:438)
	at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:402)
	at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
	at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
	at br.inf.portalfiscal.www.nfe.wsdl.nferecepcao2.NfeRecepcao2Stub.nfeRecepcaoLote2(NfeRecepcao2Stub.java:196)
	at src.br.gov.fazenda.nfe.www.envio.NFeRecepcaoCerA3.NfeRecepcaoLoteA3(NFeRecepcaoCerA3.java:101)
	at src.br.gov.fazenda.nfe.www.inicial.EmissaoPadraoNfe.emiteNotaFiscal(EmissaoPadraoNfe.java:34)
	at src.br.gov.fazenda.nfe.www.inicial.NfeEnvio.doGet(NfeEnvio.java:34)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.security.InvalidKeyException: Unsupported key type: SunPKCS11-SmartCard RSA private key, 1024 bits (id 1, token object, sensitive, unextractable)
	at sun.security.mscapi.RSACipher.engineGetKeySize(RSACipher.java:345)
	at javax.crypto.Cipher.b(DashoA13*..)
	at javax.crypto.Cipher.a(DashoA13*..)
	at javax.crypto.Cipher.init(DashoA13*..)
	at java.security.Signature$CipherAdapter.engineInitSign(Unknown Source)
	at java.security.Signature$Delegate.init(Unknown Source)
	at java.security.Signature$Delegate.chooseProvider(Unknown Source)
	at java.security.Signature$Delegate.engineInitSign(Unknown Source)
	at java.security.Signature.initSign(Unknown Source)
	at com.sun.net.ssl.internal.ssl.RSASignature.engineInitSign(Unknown Source)
	at java.security.Signature$Delegate.engineInitSign(Unknown Source)
	at java.security.Signature.initSign(Unknown Source)
	at com.sun.net.ssl.internal.ssl.HandshakeMessage$CertificateVerify.<init>(Unknown Source)
jeroqueiroz

Você insere aluma arquivo nos diretórios do Tomcat? Lib ou algum arquivo de configuração?

cinei

O código que utilizo foi adaptado com base em posts daqui mesmo.
Uso Jax Ws

Não sei se ajuda, mas vou postar meu código de envio.

public class SefazService {
	private final DaoFactory daoFactory;

	private String webServiceURL;
	private String definitionsTargetNamespaceURI;
	private String schemaTargetNamespaceURI;
	private String soapActionURI;
	private String serviceName;
	private String portName;

	private String fileCertificado;
	private int tipoCertificado;
	private String senhaCertificado;
	private String arquivoCacerts;
	private String trustStorePassword;
	private String workDir;

	public SefazService(String serviceName, DaoFactory daoFactory) throws Exception {

		this.daoFactory = daoFactory;

		this.workDir = daoFactory.getConfiguracoesDao().getParametro("WORKDIR");
		if (!(this.workDir.substring(this.workDir.length() - 1, this.workDir.length())).equals("/"))
			this.workDir = this.workDir + "/";
		
		carregarParametros(serviceName);
		
	}
	
	private void carregarParametros(String serviceName) throws Exception {
		NfeParametros nfeParametros = daoFactory.getNfeParametrosDao().getNfeParametros();
		int tpAmbiente = nfeParametros.getTipoAmbiente();
		
		boolean producao = false;
		if (tpAmbiente == 1)
			producao = true;
		else
			producao = false;

		this.fileCertificado = workDir + "certificado/" + nfeParametros.getArquivoCertificato(); //"SmartCard.cfg", "Token.cfg", "CertificadoA1.p12/pfx"
		File file = new File(this.fileCertificado);
		if (!file.exists()) {
			throw new Exception("Arquivo " + this.fileCertificado + " (carregarParametros) não encontrado!");
		}

		this.senhaCertificado = nfeParametros.getSenhaCertificado(); 
		if (producao)
			this.arquivoCacerts =  workDir + "certificado/" + nfeParametros.getArquivoKeyStore_Prod();
		else
			this.arquivoCacerts =  workDir + "certificado/" + nfeParametros.getArquivoKeyStore_Homo();
		File fileCert = new File(this.arquivoCacerts);
		if (!fileCert.exists()) {
			throw new Exception("Arquivo " + this.arquivoCacerts + " (carregarParametros) não encontrado!");
		}

		this.trustStorePassword = nfeParametros.getKeyStorePasswd(); 
		this.tipoCertificado = nfeParametros.getTipoCertificado(); //1=A1, 2=A3 (Cartão Smart), 3=A3 (Token)
		if (tipoCertificado == 1)
        	this.setCertificadoA1();
        else
    		if (tipoCertificado == 2)
            	this.setCertificadoA3(true); //Cartão Smart
            else
        		if (tipoCertificado == 3)
                	this.setCertificadoA3(false);  //Cartão Token

		NfeWebService nfeWebService = daoFactory.getNfeWebServiceDao().getService(serviceName, producao);
		
		if (producao){
			this.webServiceURL = nfeWebService.getWebServiceURL_p();
			this.definitionsTargetNamespaceURI = nfeWebService.getDefinitionsNamespaceURI_p();
			this.schemaTargetNamespaceURI = nfeWebService.getSchemaNamespaceURI_p();
			this.soapActionURI = nfeWebService.getSoapActionURI_p();
			this.serviceName = nfeWebService.getServiceName_p();
			this.portName = nfeWebService.getPortName_p();
		}else{
			this.webServiceURL = nfeWebService.getWebServiceURL_h();
			this.definitionsTargetNamespaceURI = nfeWebService.getDefinitionsNamespaceURI_h();
			this.schemaTargetNamespaceURI = nfeWebService.getSchemaNamespaceURI_h();
			this.soapActionURI = nfeWebService.getSoapActionURI_h();
			this.serviceName = nfeWebService.getServiceName_h();
			this.portName = nfeWebService.getPortName_h();
		}
	}
	/**
	 * Método que envia o xml para o WS
	 * @param xml
	 * @return
	 */
	public OutputStream sendXML(InputStream xml,String uf) throws SOAPException,Exception {
		//preparar as propriedades
		Provider provider = new Provider();
		Security.addProvider(provider);
		
		//Cria um serviço a partir do endereço do WS  
		Service service = Service.create(new URL(webServiceURL+"?wsdl"),new QName(definitionsTargetNamespaceURI, serviceName));

		//Cria um Dispatch, que é responsável por invocar o serviço
		Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(schemaTargetNamespaceURI, portName),SOAPMessage.class,Service.Mode.MESSAGE);

		//Configura o RequestContext para a Message solicitada
		Map<String, Object> rc = dispatch.getRequestContext();  
		rc.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);  
		rc.put(BindingProvider.SOAPACTION_URI_PROPERTY, soapActionURI);  
		rc.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, webServiceURL);

		// Cria um SOAPMessage Request, passando a especificação SOAP 1.2  
		MessageFactory factory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
		SOAPMessage soapMessage = factory.createMessage();

		// Optional
		soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "false");
		soapMessage.setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "utf-8");	

		// Cria o Header da mensagem 
		SOAPHeader header = soapMessage.getSOAPHeader();
		SOAPElement nfeCabecMsg = header.addChildElement("nfeCabecMsg", XMLConstants.DEFAULT_NS_PREFIX, definitionsTargetNamespaceURI);
		nfeCabecMsg.addChildElement("versaoDados").setValue("2.00");
		nfeCabecMsg.addChildElement("cUF").setValue(uf);

		// Cria o Body
		SOAPBody body = soapMessage.getSOAPBody();

		// Cria um elemento que vai ter os dados do XML    
		SOAPBodyElement nfeDadosMsg = body.addBodyElement(new QName(schemaTargetNamespaceURI, "nfeDadosMsg", XMLConstants.DEFAULT_NS_PREFIX));

		// Converte o stream (seu xml) para um Objeto DOM
		DOMResult domResult = new DOMResult();
		XMLReader reader = XMLReaderFactory.createXMLReader();
		InputSource inputSource = new InputSource(xml);
		SAXSource saxSource = new SAXSource(reader, inputSource);
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		transformer.transform(saxSource, domResult);

		//obtém o Document 
		Document document = (Document) domResult.getNode();
		//cria um elemento a partir o Document
		SOAPElement soapElement = SOAPFactory.newInstance().createElement(document.getDocumentElement());
		//adiciona no Body
		nfeDadosMsg.addChildElement(soapElement); 
		//imprime o envelope

		// invoca o WS e obtém o retorno
		SOAPMessage reply = dispatch.invoke(soapMessage);

		// Retorno
		OutputStream out = new ByteArrayOutputStream();
		reply.writeTo(out);	        
		return out;
	}
	
	private void setCertificadoA3(boolean smartCard){
		java.security.Provider p = new SunPKCS11(this.fileCertificado);
		Security.addProvider(p);
		Properties properties = System.getProperties();
		properties.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
		properties.setProperty("javax.net.ssl.keyStoreType", "PKCS11");//
		properties.setProperty("javax.net.ssl.keyStore","NONE");//
//		Se "SunPKCS11-SmartCard" não servir, usar "SunPKCS11-SCR3310" para Cartão Smart		
//		properties.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-SCR3310");     
		if (smartCard)  
			properties.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-SmartCard");  
		else // token  
			properties.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-eToken");  
		properties.setProperty("javax.net.ssl.keyStorePassword", this.trustStorePassword);
		properties.setProperty("javax.net.ssl.trustStoreType", "JKS"); // 
		properties.setProperty("javax.net.ssl.trustStore", this.arquivoCacerts);
		//
		try{
			KeyStore ks = KeyStore.getInstance("PKCS11");
			ks.load(null, this.senhaCertificado.toCharArray()); //senha do certificado
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void setCertificadoA1(){
		//preparar as propriedades

        System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

        //INICIO DO TIPO A1  
        System.setProperty("javax.net.ssl.keyStore", this.fileCertificado);  
        System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");               
        System.setProperty("javax.net.ssl.keyStorePassword", this.senhaCertificado);  
        //FIM DO TIPO A1  

        System.setProperty("javax.net.ssl.trustStoreType", "JKS");      
        System.setProperty("javax.net.ssl.trustStore", this.arquivoCacerts);//caminho do arquivo        
        System.setProperty("javax.net.ssl.trustStorePassword", this.trustStorePassword);                   
	}

	public String getWebServiceURL() {
		return webServiceURL;
	}

	public void setWebServiceURL(String webServiceURL) {
		this.webServiceURL = webServiceURL;
	}

	public String getDefinitionsTargetNamespaceURI() {
		return definitionsTargetNamespaceURI;
	}

	public void setDefinitionsTargetNamespaceURI(
			String definitionsTargetNamespaceURI) {
		this.definitionsTargetNamespaceURI = definitionsTargetNamespaceURI;
	}

	public String getSchemaTargetNamespaceURI() {
		return schemaTargetNamespaceURI;
	}

	public void setSchemaTargetNamespaceURI(String schemaTargetNamespaceURI) {
		this.schemaTargetNamespaceURI = schemaTargetNamespaceURI;
	}

	public String getSoapActionURI() {
		return soapActionURI;
	}

	public void setSoapActionURI(String soapActionURI) {
		this.soapActionURI = soapActionURI;
	}

	public String getServiceName() {
		return serviceName;
	}

	public void setServiceName(String serviceName) {
		this.serviceName = serviceName;
	}

	public String getPortName() {
		return portName;
	}

	public void setPortName(String portName) {
		this.portName = portName;
	}
}
jeroqueiroz

Então você não faz utilização do Axis2 correto?

Você utiliza NetBeans ou Eclipse?

Quando você gera um Web Service Client qual o nome da classe é gerada?

jeroqueiroz

Poderia enviar os imports da classe?

Aqui tem opções de algumas de import e fiquei na dúvida.

cinei
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.util.Map;
import java.util.Properties;

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import sun.security.pkcs11.SunPKCS11;

import br.com.sge.dao.DaoFactory;
import br.com.sge.nfe.model.NfeParametros;
import br.com.sge.nfe.model.NfeWebService;

import com.sun.net.ssl.internal.ssl.Provider;

/**
 * Classe responsável por criar uma Message e consumir o Web Service.
 * 
 * Arquivo: SefazService.java
 * Data   : 16/02/2011
 * Hora   : 14:01:27
 * Fonte: http://www.guj.com.br/java/233399-nfe-v200---veja-como-consumir-o-ws
 * 
 * Fonte 2: http://www.javac.com.br/jc/posts/list/46-nfe-status-do-servico-com-certificados-a3-cartao-e-token-webservice-20.page
 */

Você vai perceber que há vários parametros. Eles estão em Banco de de Dados.

jeroqueiroz

Seria possível a você especificar o que se refere cada parâmetro?

Desde já agradeço.

cinei

Se você fosse enviar um lote para o Paraná, seria assim:

private String webServiceURL = "https://homologacao.nfe2.fazenda.pr.gov.br/nfe/NFeRecepcao2";  
private String definitionsTargetNamespaceURI = "http://www.portalfiscal.inf.br/nfe/wsdl/NfeRecepcao2";
private String schemaTargetNamespaceURI = "http://www.portalfiscal.inf.br/nfe/wsdl/NfeRecepcao2";
private String soapActionURI = "http://www.portalfiscal.inf.br/nfe/wsdl/NfeRecepcao2/nfeRecepcaoLote2";  
private String serviceName = "NfeRecepcao2";
private String portName = "NfeRecepcaoServicePort";

private String fileCertificado; // Arquivo do certificado (se for A1, é o proprio certificado; se for A3 será o arquivo com as configurações p/carregar o certificado
private int tipoCertificado; // Tipo de certificado 1=A1, 2=A3 (Cartão Smart), 3=A3 (Token)
private String senhaCertificado; // Senha do certificado A1 ou A3
private String arquivoCacerts; // Chave publica e cadeia de certificados da sua Receita
private String trustStorePassword; // Senha das chaves publicas
private String workDir; // Pasta que estão os arquivos acima

Espero que ajude

jeroqueiroz

A Classe DaoFactory é a parte de comunicação com o BD?

A NfeParametros seria um Model?

Você pode disponibilizar estas classes?

Se não puder enviar, se possível responda os questionamentos acima.

cinei

jeroqueiroz:
A Classe DaoFactory é a parte de comunicação com o BD?
A NfeParametros seria um Model?
Você pode disponibilizar estas classes?
Se não puder enviar, se possível responda os questionamentos acima.

Por mim, não há nenhum problema em disponibilizar as classes.
Acontece que tenho um grande sistema, com o módulo Nfe incluido. Isso vai te confundir mais porque há uma série de coisas não relacionados à Nfe.
Sugiro que dê uma boa lida neste post: http://www.guj.com.br/java/233399-nfe-v200—veja-como-consumir-o-ws e adapte ao seu projeto.
Outro post que também pode ajudar: http://www.javac.com.br/jc/posts/list/46-nfe-status-do-servico-com-certificados-a3-cartao-e-token-webservice-20.page

Editando:

DaoFactory é uma classe intermediaria para comunicação com o BD (a antiga Fábrica de Dao);

NfeParametros contém os parâmetros para Nfes;

NfeWebService contém os endereços dos WebServices.

Se você seguir a risco o Link do Guj acima, você consegue. Depois você aperfeiçoa.

jeroqueiroz

Prezado cinei,

Agradeço sua atenção, tem sido muito valida.

Os post que você citou acima eu já conhecia um dos inclusive é este que utilizo, porém ele não esta rodando no tomcat nem no Jboss.

E exatamente a classe que uso e quando rodo Java Application ela vai, porem quando rodo Web não vai. Apresenta o erro.

P


Caused by: java.security.InvalidKeyException: Unsupported key type: SunPKCS11-SmartCard RSA private key, 1024 bits (id 1, token object, sensitive, unextractable)

Vamos ler as msgs de erro !!! Pra começar lembre-se que vc tem o conteiner web(tomcat) entre a sua classe e o webservice e vc tem que informar ao tomcat as libs necessarias. No seu teste vc ta usando token ?Pois na msg é o que ta mostrando! E lembre que-se que o servidor é um equipamento e o cliente é outro aonde teoricamente tem que estar o token. O que o pessoal faz é usar um certificado A1(arquivo) e não um A3(token) quando se tem um servidor executando a aplicação de envio de NFe

jeroqueiroz

Prezado pbnf,

Obrigado pela ajuda.

Estou usando o Eclipse + Tomcat + Axis2. O erro esta no uso desde os testes da aplicação que ainda não conseguir fazer rodar.

Esta e justamente a minha dúvida. Quais as configurações que preciso fazer no Tomcat? Quias libs adicionar?

Ou configurações a serem feitas em arquivos de configurações?.

Desde já agradeço a sua ajuda.

jeroqueiroz

Prezado pbnf,

Alguma resposta?

jeroqueiroz

Conseguiu resolver meu problema em partes, pois para certificado A1 resolveu, porém necessito para A3 alguém sabe informar como devo proceder?

Segue resolução:

Acerte o servidor.xml do tomcat para:

&lt;Connector port="8443" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" disableUploadTimeout="true" acceptCount="100" keystoreFile="c:\java\certificado.p12" keystoreType="PKCS12" keystorePass="certificado" debug="0" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /&gt;

presta atenção, tem um parâmetro novo no Connector Port:

Conteúdo visto neste post: http://www.guj.com.br/java/29710-tomcat--https/2#1288066

cinei

jeroqueiroz, montei os pacotes há algum tempo.
Utilizo VRaptor 3.3.1. Exceto alguns pacotes, quase todos estão junto com o VRaptor.
Acrescentei Quartzo, Mail, Jasper, entre outros específicos.
Outras libs que estão no projeto (mas talvez nem sejam necessárias):

serializer.jar
xalan.jar
xercesImpl.jar
xml-apis.jar
xsltc.jar

Todas as libs estão adicionadas no path Tomcat.
Testei com certificados A1 e A3 (utilizo mais o A3 instalado no servidor)

jeroqueiroz

Prezado Cinei,

Obrigado a resposta. Quanto as libs resolvi colocar todas as libs no tomcat e retirei do projeto.

Estou necessitando resolver agora sobre o ultimo post que fiz, você tem alguma sugestão?

POST:

cinei

Não posso te ajudar.
Acesso o Certificado pelo meu aplicativo conforme post acima.

jeroqueiroz

Prezado cinei,

Você fez alguma configuração no Tomcat para aceitar HTTPS?

Ou fez alguma configuração no web.xml, server.xml ?

Desde já agradeço atenção.

cinei

Não foi feita nenhuma configuração especial na máquina ou no Tomcat.
O comunicação é via Internet e já está logado. O sistema NÃO espera se conectar.

jeroqueiroz

cinei,

Você pode mim ajudar em algo com este tópico:

Estou tendo o seguinte erro abaixo quando tendo rodar a aplicação para envio da NFe para o WebService da SEFAZ.

Estive olhando e soube que tenho que fazer uma configuração em algum arquivo de segurança do Java para habilitar algo referente ao “SunPKCS11-SmartCard”, ainda tive o seguinte link, porém para mim não ficou muito claro. Alguém pode ajudar como fazer?

LINK - http://download.oracle.com/javase/7/docs/technotes/guides/security/p11guide.html#KeyToolJarSigner

Desde já agradeço a atenção

cinei

Pela mensagem, você está tentando setar um Certificado tipo A3 em cartão smart.
Veja a seguir as configurações (da forma que tenho em um cliente):
Para acessar o Certificado tipo A3 em cartão smart:

java.security.Provider p = new SunPKCS11("Arquivo de configuração das bibliotecas do cartão"); // Veja exemplo abaixo  (chamo de token.cfg)
		Security.addProvider(p);
		Properties properties = System.getProperties();
		properties.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
		properties.setProperty("javax.net.ssl.keyStoreType", "PKCS11");
		properties.setProperty("javax.net.ssl.keyStore","NONE");
		properties.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-SmartCard");  
		properties.setProperty("javax.net.ssl.keyStorePassword", this.trustStorePassword); //Senha para acessa a cadeia de certificados públicos dos WebServices da Receita
		properties.setProperty("javax.net.ssl.trustStoreType", "JKS"); // 
		properties.setProperty("javax.net.ssl.trustStore", this.arquivoCacerts); // Arquivo com a cadeia, gerado pelo programa InstallCert (no link que te informei)
		//
		try{ // Este try precisa ser melhorado para retornar a mensagem ao usuário (use a maneira mais adequada para você)
			KeyStore ks = KeyStore.getInstance("PKCS11");
			ks.load(null, this.senhaCertificado.toCharArray()); //senha do certificado
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

Exemplo do Arquivo de configuração das bibliotecas do cartão para uso no Windows. Verificar onde fica a DLL do seu cartão para a versão do seu Windows.
Conteúdo de meu arquivo token.cfg:

name = SmartCard

library = C:/WINDOWS/system32/aetpkss1.dll

O cartão deve ser instalado no WebServer com os drives do fornecedor.
Não sei te dizer se a DLL aetpkss1.dll vem com o Windows ou se foi inserida no momento da instalação do cartão.
No Tomcat não fiz nenhuma configuração para atender esta situação.

Espero que ajude.

jeroqueiroz

cinei,

Quando você diz:

O cartão deve ser instalado no WebServer com os drives do fornecedor.

Você esta querendo se referir que deve ser feita instalação na maquina onde estará a aplicação? Ou você quer dizer que necessito de algo no Tomcat?

Apesar que você falou que não instalou nada no Tomcat.

Veja a classe que estou usando o seu código se encaixa neste ou tereia que fazer a alteração da forma utilizada:

ConfigServise configServise = new ConfigServise();
            Provider p = new sun.security.pkcs11.SunPKCS11(configServise.leitorGemPC_Perto());  
            Security.addProvider(p);  
            char[] pin = senhaDoCertificado.toCharArray();  
            KeyStore ks = KeyStore.getInstance("pkcs11", p);  
            ks.load(null, pin);  
            
            String alias = "";  
            Enumeration&lt;String&gt; aliasesEnum = ks.aliases();  
            while (aliasesEnum.hasMoreElements()) {  
                alias = (String) aliasesEnum.nextElement();  
                if (ks.isKeyEntry(alias)) break;  
            }  
            X509Certificate certificate = (X509Certificate) ks.getCertificate(alias);  
            PrivateKey privateKey = (PrivateKey) ks.getKey(alias, senhaDoCertificado.toCharArray());  
            SocketFactoryDinamico socketFactoryDinamico = new SocketFactoryDinamico(certificate, privateKey);  
            socketFactoryDinamico.setFileCacerts(arquivoCacertsGeradoTodosOsEstados);  
  
            Protocol protocol = new Protocol("https", socketFactoryDinamico, SSL_PORT);    
            Protocol.registerProtocol("https", protocol);
            
            //IMPORTANTE: O XML já deve ser assinado antes do envio. Lendo o Xml de um arquivo Gerado.
            StringBuilder xml = new StringBuilder();
            String linha = null;
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(caminhoArquivoXML), "ISO-8859-1"));
            while ((linha = in.readLine()) != null) {
                xml.append(linha);
            }
            in.close();

            OMElement ome = AXIOMUtil.stringToOM(xml.toString());

            Iterator&lt;?&gt; children = ome.getChildrenWithLocalName("NFe");  
            while (children.hasNext()) {
	            OMElement omElement = (OMElement) children.next();  
	            if ((omElement != null) && ("NFe".equals(omElement.getLocalName()))) {  
	            	omElement.addAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe", null);  
	            }
            }

            NfeRecepcao2Stub.NfeDadosMsg dadosMsg = new NfeRecepcao2Stub.NfeDadosMsg();
            dadosMsg.setExtraElement(ome);
            NfeRecepcao2Stub.NfeCabecMsg nfeCabecMsg = new NfeRecepcao2Stub.NfeCabecMsg();
            
            //Código do Estado.
            nfeCabecMsg.setCUF(codigoDoEstado);
            
            //Versao do XML
            nfeCabecMsg.setVersaoDados("2.00");

            NfeRecepcao2Stub.NfeCabecMsgE nfeCabecMsgE = new NfeRecepcao2Stub.NfeCabecMsgE();
            nfeCabecMsgE.setNfeCabecMsg(nfeCabecMsg);

            NfeRecepcao2Stub stub = new NfeRecepcao2Stub(url.toString());
            NfeRecepcao2Stub.NfeRecepcaoLote2Result result = stub.nfeRecepcaoLote2(dadosMsg, nfeCabecMsgE);

Sobre o mesmo questionamento que fiz a a você anteriormente, veja a resposta que tive:


Certificado inválido. Aconteceu comigo também.
Por isso que o meu é desktop. Pois para eu resolver este problema era necessário um certificado SSL do tipo Servidor.
O valor desse certificado fica aproximadamente R$ 3.000,00/ano.

Você sabe informar algo sobre esta informação?

Seu certificado é deste tipo?

Agradeço a atenção e ajuda.

P

jeroqueiroz:

Alguem utiliza Tomcat em sua aplicação par emissão de NF-e?

Ou utiliza aplicação Web para emissão? Qual server usa?

Voltando ao assunto temos que saber algumas coisas:

1º Vc pode usar certificado A1(arquivo) no servidor então o arquivo do cert. tem que ficar no servidor e no codigo java vc vai fazer referencia ao arquivo do certificado e com a respectiva senha.
2º Se deseja usar cert. A3(token USB ou Smartcard) a logica diz pra ser lido e validado no cliente(browser) então tem todo um tramite de dados e certificados entre servidor e cliente que é bem mais complicado pois vc tem que habilitar o tomcat pra trabalhar a segurança no modo CLIENT-CERT e habilitar o SSL no tomcat.

Acho que emissão de NFe o ideal é usar o certificado A1.

jeroqueiroz

pbnf,

Obrigado pela Resposta. Realmente fiz a opção por mudar para A1.

Agradeço a atenção.

Criado 21 de julho de 2011
Ultima resposta 24 de ago. de 2011
Respostas 33
Participantes 3