Certificado A3 - NFE

Estou finalizando uma aplicação de NFe, gostaria de pedir a senha do cartao na inicialização do sistema para que o usuario possa logar, então pergunto: Como posso obter a senha do cartão para comparar com a senha digitada pelo usuário?

Agradeço desde já qualquer ajuda!

Carla, na verdade vc não pede a senha no cartão, vc pede pro usuário digitar na aplicação ou armazena isso em algum lugar e daí “passa” para o java validar no cartão:

System.setProperty(“javax.net.ssl.keyStorePassword”, “<aqui_vai_a_senha>”);

Se por acaso depois de inicializar o smartcard ele retornar uma exception, aí sim vc consegue capturar se o login foi inválido ou não (uma exception é lançada).

Att.
Edson.

Bom dia pessoal,

Estou com um problema no certificado A3 com token da rainbow.

Meu token.cfg etá assim:

name=Safenetikey2032 library=c:/windows/system32/dkck201.dll

Um pedaço do meu código está assim:

[code] Provider p = new sun.security.pkcs11.SunPKCS11(getcertificadoFile());

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

System.setProperty("javax.net.ssl.keyStoreType", "PKCS11");
System.setProperty("javax.net.ssl.keyStore", "NONE");
System.setProperty("javax.net.ssl.keyStorePassword", getcertificadoPassword());

System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", CERTIFICADO_ARQUIVO_PR);
System.setProperty("javax.net.ssl.trustStorePassword", CERTIFICADO_SENHA_PR);

KeyStore ks = KeyStore.getInstance("PKCS11");
ks.load(null, certificado.getcertificadoPassword().toCharArray());

Enumeration<String> aliasesEnum = ks.aliases();
while (aliasesEnum.hasMoreElements()) {  
    String alias = (String) aliasesEnum.nextElement();
        
    System.out.println("<INICIO -------------------------------------------------------------------------------------------------");
    System.out.println("----> Certificado alias: " + alias + "    Key store type: " + ks.getType());
    X509Certificate certif = (X509Certificate)ks.getCertificate(alias);
    System.out.println( "SN =     " + certif.getSerialNumber().toString(16) );
    System.out.println( "Issuer = " + certif.getIssuerDN().toString() );
    System.out.println( "subject= " + certif.getSubjectDN().toString() );
    System.out.println("<FIM ----------------------------------------------------------------------------------------------------");
}

[/code]

No token existe a seguinte cadeia de chaves:
[color=blue]AC Raiz
AC Secretaria da refeita federal do brasil
AC Serasa RFB
Empresa com o certificado E-CNPJ
[/color]

Quando eu executo o programa o retorno é o seguinte:

[color=red]<INICIO -------------------------------------------------------------------------------------------------
----> Certificado alias: 2a12a8fb-d26c-45dd-acdf-4b2e94a8a185 Key store type: PKCS11
SN =5
Issuer =CN=Autoridade Certificadora Raiz Brasileira v1, OU=Instituto Nacional de Tecnologia da Informacao - ITI, O=ICP-Brasil, C=BR
subject=CN=AC Secretaria da Receita Federal do Brasil, O=ICP-Brasil, C=BR
<FIM ----------------------------------------------------------------------------------------------------
[/color]

Ou seja não está me retornando o certificado da empresa com E-CNPJ e sim o segundo nível da raiz, neste caso AC Secretaria da REceita Federal do Brasil

Alguém já passou por isso ?

[color=darkred]Obs: No cartão tipo A3 está tudo certo o problema dá apenas no token.[/color]

Por gentileza, se alguém puder me ajudar eu agradeço.

Um abraço a todos.

Boa tarde,

Na minha aplicação quando faço a primeira assinatura de um xml com o Certificado A3 ele me pede a senha com um tela do proprio Token, apartir disso não me é solicitado mais a senha…

Gostaria de saber como resolver isso… alguma forma de executar a assinatura do xml sem solicitar ao usuario a senha.

Pude perceber também que é nessa linha “signature.sign(dsc);” que apresenta a tela de digitação da senha:

		Reference ref = fac.newReference(uri, fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);
		System.out.print(" 444444");
		SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null) ,fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref) );
		System.out.print(" 55555");
		XMLSignature signature = fac.newXMLSignature(si, ki);
		System.out.print(" 66666");
		DOMSignContext dsc = new DOMSignContext(privateKey, doc.getElementsByTagName("NFe").item(0));
		System.out.print(" 7777777");
		signature.sign(dsc);
		System.out.print(" 88888888");

Desde já Obrigado…
Miguel

eu faço assim:

while (aliasEnum.hasMoreElements()) {
String aliasKey = (String) aliasEnum.nextElement();
System.out.println(aliasKey);
System.out.println(ks.getCertificate(aliasKey));
}

ué, mas o certo não é pedi td vez p/ inserir a senha???rsrs

Eu gostaria de que o usuario não tivesse que digitar a senha… ela seria passada como parâmetro…

[quote=acmedis]Bom dia pessoal,

Eu tenho um certificado A3, em dispositivo USB.
Mas nem sei por onde começar.

Utilizando certificados A1, (*.pfx) esta tudo blz, funcionando perfeitamente.

Mas agora eu preciso desenvolver assinatura utilizando o A3.
Preciso criar um arquivo token.cfg ? e configurar alguma coisa nele ?
[/quote]Estou na mesmíssima situação, se alguém puder me dar umas dicas agradeço.

Aproveito para perguntar: meu cliente comprou o certificado A3 e está com ele agora, só que ele está muito longe, tem jeito de ele me enviar o conteúdo do dispositivo USB para eu fazer os testes aqui e depois instalar na maquina dele?

Sem o token e o cartão você não tem como testar!
Apenas se for A1.

[color=brown]Ninguém teria um exemplo de como enviar o XML? (já está validado e assinado)[/color]

web service?

Sim, estou trabalhando com a versão 2.

Preciso saber como pego o XML e faço e envio.

import java.net.URL;
import javax.swing.JOptionPane;
import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class Conexao implements Runnable {

private String url;
private String nameSpace;
private String metodo;
private String xml;
private String parametro;



public void setMetodo(String metodo) {
    this.metodo = metodo;
}

public void setNameSpace(String nameSpace) {
    this.nameSpace = nameSpace;
}

public void setParametro(String parametro) {
    this.parametro = parametro;
}

public void setXml(String xml) {
    this.xml = xml;
}

public void setURL(String url) {
    this.url = url;
}

public void run() {

    String result = null;
    try {
        URL endpoint = new URL(url);
        Service service = null;
        try {
            service = new Service();
        } catch (NoClassDefFoundError e) {
            e.printStackTrace();
        }
        Call chamada = (Call) service.createCall();
        chamada.setTimeout(0);
        chamada.setTargetEndpointAddress(endpoint);
        chamada.setOperationName(new QName(nameSpace, metodo));
        chamada.addParameter(parametro, org.apache.axis.Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
        chamada.setReturnType(org.apache.axis.Constants.XSD_STRING);
        result = (String) chamada.invoke(new Object[]{xml});   //Retorna na string result o retorno do seu webservice.
        System.out.println(result);   

        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

//Pra usar a classe você seta os valores e roda a thread :smiley:

        Conexao conect = new Conexao();
        conect.setMetodo("AQUI_VAI_O_NOME_DO_SEU_METODO");
        conect.setNameSpace("AQUI_VAI_SEU_NAMESPACE");
        conect.setParametro("AQUI_VAI_O_NOME_DO_PARAMETRO");
        conect.setURL("AQUI_VAI_SEU_URL");
        conect.setXml("AQUI_VAI_O_SEU_XML");
        Thread conexao = new Thread(conect);
        conexao.start();

Não sei se era isso que você queria, se foi espero ter ajudado.
Qualquer coisa posta ai de novo.

Na verdade eu queria saber como enviar com as classes geradas dos WSDL.

Eu até uso Axis, mas o Axis2, é diferente, mas eu não tenho experiência nenhuma com ele.

De qualquer forma valeu pela ajuda.

Como passei pelo problema de todo mundo aqui vou deixar algumas dicas para fazer a integração do NFe com certificados A3.
Primeiro passo… montar o ambiente, no caso estou usando Spring 3, Apache CXF e Maven2…
O danado do POM:

[code]
3.0.3.RELEASE
2.2.10

org.apache.maven.plugins maven-compiler-plugin 2.3.2 1.6 1.6 javax.inject inject-api 1.0 org.springframework spring-core ${spring-version} org.springframework spring-context-support ${spring-version} org.springframework spring-web ${spring-version} org.apache.cxf cxf-rt-frontend-jaxws ${cxf-version} org.apache.cxf cxf-rt-transports-http ${cxf-version} [/code]

Segundo passo: Configurar o Spring

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"	
	xmlns:beans="http://www.springframework.org/schema/beans" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:sec="http://cxf.apache.org/configuration/security" 
	xmlns:http="http://cxf.apache.org/transports/http/configuration"
	xmlns:soap="http://cxf.apache.org/bindings/soap"	
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
		http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
    	http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
        http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd        
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

	<import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

	<http:conduit name="https://nfe.sefaz.go.gov.br/OServico">
		<http:tlsClientParameters>	    
		    <sec:keyManagers keyPassword="***">
	      		<sec:keyStore type="PKCS11" password="***" provider="SunPKCS11-SmartCard" resource="p11.conf"/> 		
	      	</sec:keyManagers>
	      	<sec:trustManagers>				
				<sec:keyStore type="JKS" password="***" resource="myJks.jks"/>
			</sec:trustManagers>
		</http:tlsClientParameters>		
   	</http:conduit>
	
	<jaxws:client id="servico" 
		address="https://nfe.sefaz.go.gov.br/OServico" 
		serviceClass="br.com.teste.OServico">
		<jaxws:binding>
			<soap:soapBinding version="1.2"/>
		</jaxws:binding>		
	</jaxws:client>
   	
</beans>

Terceiro passo: O arquivo p11
Esse arquivo serve para apontar para a dll do fabricante do leitor
O name deve bater com o name do spring definido no provider do keystore “SunPKCS11-name”

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

Quarto passo: A classe main

[code]package br.com.datatraffic.sefazgo;

import java.security.Security;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import sun.security.pkcs11.SunPKCS11;

public class Main {

public static void main(String[] args) throws Exception {
	Security.addProvider(
		new SunPKCS11(Thread.currentThread().getContextClassLoader().getResourceAsStream("p11.conf"))
	);
	BeanFactory factory = new ClassPathXmlApplicationContext("spring-config.xml");
	OServico servico = (OServico) factory.getBean("servico");
	String resultado = servico.facaAlgo("Teste");
	System.out.println(resultado);
}

}[/code]

É isso aí… mais simples impossível

[quote=rickasmbh]boa noite prezados,

O certificado A3 para web como pode ser desenvolvido.

Exemplo tenho o servidor e o client side, no client que ele pluga o token na sua máquina ai leio o certificado, teria alguma opção de ler esse token no cliente e enviar as informações do certificado para o servidor?

Preciso disso pois será o servidor responsável por conectar com a prefeitura.

Valeu galera.[/quote]

Estou nessa mesma situação. Como assinar um XML estando o mesmo no servidor e o certificado digital no cliente?

Alguém tem uma solução?

[quote=mvrochabh][quote=rickasmbh]boa noite prezados,

O certificado A3 para web como pode ser desenvolvido.

Exemplo tenho o servidor e o client side, no client que ele pluga o token na sua máquina ai leio o certificado, teria alguma opção de ler esse token no cliente e enviar as informações do certificado para o servidor?

Preciso disso pois será o servidor responsável por conectar com a prefeitura.

Valeu galera.[/quote]

Estou nessa mesma situação. Como assinar um XML estando o mesmo no servidor e o certificado digital no cliente?

Alguém tem uma solução?[/quote]

E ai alguem conseguiu utilizar o certificado do tipo A3 na WEB? Eu pensei em usar um Applet mas não sei se vai dar certo.

[quote=rafaelbtz][quote=mvrochabh][quote=rickasmbh]boa noite prezados,

O certificado A3 para web como pode ser desenvolvido.

Exemplo tenho o servidor e o client side, no client que ele pluga o token na sua máquina ai leio o certificado, teria alguma opção de ler esse token no cliente e enviar as informações do certificado para o servidor?

Preciso disso pois será o servidor responsável por conectar com a prefeitura.

Valeu galera.[/quote]

Estou nessa mesma situação. Como assinar um XML estando o mesmo no servidor e o certificado digital no cliente?

Alguém tem uma solução?[/quote]

E ai alguem conseguiu utilizar o certificado do tipo A3 na WEB? Eu pensei em usar um Applet mas não sei se vai dar certo.[/quote]

o diogo.soares postou uma solução alguns posts acima do seu, vc viu ?

att,

[quote=pedruhenrik][quote=rafaelbtz][quote=mvrochabh][quote=rickasmbh]boa noite prezados,

O certificado A3 para web como pode ser desenvolvido.

Exemplo tenho o servidor e o client side, no client que ele pluga o token na sua máquina ai leio o certificado, teria alguma opção de ler esse token no cliente e enviar as informações do certificado para o servidor?

Preciso disso pois será o servidor responsável por conectar com a prefeitura.

Valeu galera.[/quote]

Estou nessa mesma situação. Como assinar um XML estando o mesmo no servidor e o certificado digital no cliente?

Alguém tem uma solução?[/quote]

E ai alguem conseguiu utilizar o certificado do tipo A3 na WEB? Eu pensei em usar um Applet mas não sei se vai dar certo.[/quote]

o diogo.soares postou uma solução alguns posts acima do seu, vc viu ?

att,[/quote]

Vi sim, mas ali ele usa Spring e tem até um teste com classe Main e tal.

Aqui meu aplicativo é muito simples é feito em JSF e tem uma unica pagina pra fazer upload de arquivo TXT, o sistema converte em XML assina e faz todo o processo de envio, já está funcionando perfeitamente com A1, agora surgiu esse requisito de fazer funcionar com A3 e ai está minha dúvida como fazer o cliente informar os dados do certificado via browser para que eu consuma o WebService no servidor.

Eu pensei em Applet inclusive utilizei pra testes um código seu, onde vc pega a lista de certificados instalados no Windows, meu problema é que eu não posso serializar o KeyStore para enviá-lo ao servidor para este utilizar na assinatura e no consumo do WebService.

Ou seja existe algum jeito do usuário informar os dados do certificado (nesse caso A3 Card) no Browser para ser utilizado no servidor?

Também estou com uma dúvida similar. Tenho aqui um sistema web, e preciso implementar a assinatura via certificado A3.

Daí vem, então, o seguinte problema: o cartão está na máquina cliente, e o sistema está rodando no servidor. Não é viável manter o certificado A3 no servidor, nem possível transmitir o certificado do cliente para o servidor, pois, por definição, todo o processo de encriptação/assinatura do A3 é efetuado pelo microcontrolador dentro do smartcard, ou seja, a chave privada nunca sai do cartão.

Tendo isto em vista, tanto o processo de assinatura quanto a comunicação com o webservice precisariam ser efetuados na máquina cliente.

Alguém tem alguma idéia de qual seria a melhor maneira de implementar isto?

– editado –

O artigo em http://www.developer.com/security/print.php/11580_3587361_2 ensina como criar um applet para assinar arquivos locais via smartcard e enviá-los ao servidor. Ao que tudo indica, esta solução poderia ser adaptada para assinar uma NFe via web.

Alguem poderia postar um exemplo de geração e envio do xml usando o certificado a3?

Estou precisando muito desse exemplo.

Obrigado pela atenção.

Abraços