Problemas com Assinatura Digital

iai pessual, blz?

estou construindo um assinador para uma assinatura digital, mas estou com bastante problemas. Tenho um código que foi passado para mim q possivelmente assina um xml, porem não consigo fazer ele executar com sucesso.

Segue o assinador:

[code]package br.cienci.nfe.servico.assinador;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class Assinador
{
private static final String C14N_TRANSFORM_METHOD = “http://www.w3.org/TR/2001/REC-xml-c14n-20010315”;

// tipo
// '1' - NFE
public static final String NFE = "1";
// '2' - CANCELAMENTO
public static final String CANCELAMENTO = "2";
// '3' - INUTILIZACAO
public static final String INUTILIZACAO = "3";

public void assinar(String caminhoXml, String caminhoCertificado, String senha, String caminhoXmlNovo, String tipo) throws Exception
{

	//
	String tag = "";
	if(tipo.equals(NFE))
		tag = "infNFe";
	else if (tipo.equals(CANCELAMENTO))
		tag = "infCanc";
	else if (tipo.equals(INUTILIZACAO))
		tag = "infInut";


	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	factory.setNamespaceAware(true);
	DocumentBuilder builder = factory.newDocumentBuilder();
	Document docs = builder.parse(new File(caminhoXml));

	XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());

	// Create a Reference to the enveloped document (in this case,
	// you are signing the whole document, so a URI of "" signifies
	// that, and also specify the SHA1 digest algorithm and
	// the ENVELOPED Transform.
	ArrayList transformList = new ArrayList();
	TransformParameterSpec tps = null;
	Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED,tps);
	Transform c14NTransform = fac.newTransform(C14N_TRANSFORM_METHOD, tps);
	transformList.add(envelopedTransform);
	transformList.add(c14NTransform);

	//Reference ref = fac.newReference("#" + id, fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);
	Reference ref = fac.newReference("", fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);
	// Create the SignedInfo.
	SignedInfo si = fac
			.newSignedInfo(fac.newCanonicalizationMethod(
					CanonicalizationMethod.INCLUSIVE,
					(C14NMethodParameterSpec) null), fac
					.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
					Collections.singletonList(ref));

	// Load the KeyStore and get the signing key and certificate.
	///Provider p = new sun.security.pkcs11.SunPKCS11("c:/taliam/sclara.cer");
	//Security.addProvider(p);
	//KeyStore ks = KeyStore.getInstance("PKCS11");
	//ks.load(null, new String("safeweb").toCharArray());

	KeyStore ks = KeyStore.getInstance("PKCS12");
	ks.load(new FileInputStream(caminhoCertificado), senha.toCharArray());
	Enumeration aliasesEnum = ks.aliases();
	String alias = "";
	while (aliasesEnum.hasMoreElements()) {
		alias = (String) aliasesEnum.nextElement();

		if (ks.isKeyEntry(alias)) {
			//System.out.println(alias);
			break;
		}
	}

	// Original
	//KeyStore ks = KeyStore.getInstance("JKS");
	//ks.load(new FileInputStream("santaclara.jks"), "RAIMUNDO".toCharArray());

	//
	KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(senha.toCharArray()));

	X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
	// Create the KeyInfo containing the X509Data.
	KeyInfoFactory kif = fac.getKeyInfoFactory();
	List x509Content = new ArrayList();
	// x509Content.add(cert.getSubjectX500Principal().getName());

	x509Content.add(cert);
	X509Data xd = kif.newX509Data(x509Content);
	KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

	// Instantiate the document to be signed.
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	dbf.setNamespaceAware(true);
	Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(caminhoXml));

	// Create a DOMSignContext and specify the RSA PrivateKey and
	// location of the resulting XMLSignature's parent element.
	DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());

	// Create the XMLSignature, but don't sign it yet.
	XMLSignature signature = fac.newXMLSignature(si, ki);

	// Marshal, generate, and sign the enveloped signature.
	signature.sign(dsc);

	// Output the resulting document.
	OutputStream os = new FileOutputStream(caminhoXmlNovo);
	TransformerFactory tf = TransformerFactory.newInstance();
	Transformer trans = tf.newTransformer();
	trans.transform(new DOMSource(doc), new StreamResult(os));

	// Find Signature element.
	NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");

	if (nl.getLength() == 0) {
		throw new Exception("Cannot find Signature element");
	}
	/*
	// Create a DOMValidateContext and specify a KeySelector and document
	// context.
	DOMValidateContext valContext = new DOMValidateContext( new X509KeySelector(ks), nl.item(0));
	// Unmarshal the XMLSignature.
	XMLSignature signatures = fac.unmarshalXMLSignature(valContext);
	// Validate the XMLSignature.
	boolean coreValidity = signatures.validate(valContext);
	// Check core validation status.
	if (coreValidity == false) {
		System.err.println("Falha na Assinatura!");
	} else {
		System.out.println("Assinatura Correta!");
	}
*/
}

}
[/code]

e o erro:

java.io.IOException: parseAlgParameters failed: PBE AlgorithmParameters not available at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.parseAlgParameters(PKCS12KeyStore.java:527) at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1267) at java.security.KeyStore.load(KeyStore.java:1185) at br.com.cienci.nfe.signature.Assinador.assinar(Assinador.java:103) at br.com.cienci.nfe.signature.Assinador.main(Assinador.java:192) Caused by: java.security.NoSuchAlgorithmException: PBE AlgorithmParameters not available at sun.security.jca.GetInstance.getInstance(GetInstance.java:142) at java.security.Security.getImpl(Security.java:659) at java.security.AlgorithmParameters.getInstance(AlgorithmParameters.java:113) at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.parseAlgParameters(PKCS12KeyStore.java:523) ... 4 more

alguem ai sabe oq preciso fazer para resolver esse problema?
vlw

O mais provável é que o tal código funcione com Java 6.0 mas não com Java 5.0.

o problema é que eu ja estou tentando rodar ele com o java 6…

e em outro computador esse codigo funciona…(pelo menos é oq me disseram…rsrs)

se vc puder me ajudar lhe agradeço mto…
vlw

Acho que o problema é o arquivo de “keystore” (caminhoCertificado). Ele está no formato PKCS12? Faça um teste usando o keytool.

depois de apanhar mto desse código e de horas tentando achar algo sobre isso, acabei vendo algo sobre esse keytool…porem ainda não me aprofundei nele…

por quais razões vc acha q é isso?..como utilizar esse keytool?..como fazer esse teste?..ja q estou usando PKCS12…oq devo fazer?..

vcs podem me dar uma ajuda com isso?..creio q esteja próximo de resolver esse problema, porem ja pesquisei e não achei nda q possa resolver ainda…

como disse, qualquer ajuda será bem vinda.
Vlw

java.io.IOException: parseAlgParameters failed: PBE AlgorithmParameters not available
        at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.parseAlgParameters(PKCS12KeyStore.java:527)
        at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1267)
        at java.security.KeyStore.load(KeyStore.java:1185)
        at br.com.cienci.nfe.signature.Assinador.assinar(Assinador.java:103)
        at br.com.cienci.nfe.signature.Assinador.main(Assinador.java:192)
Caused by: java.security.NoSuchAlgorithmException: PBE AlgorithmParameters not available
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:142)
        at java.security.Security.getImpl(Security.java:659)
        at java.security.AlgorithmParameters.getInstance(AlgorithmParameters.java:113)
        at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.parseAlgParameters(PKCS12KeyStore.java:523)
        ... 4 more

Por causa do erro que aparece na stacktrace: PBE é o mecanismo de criptografar um arquivo usando uma senha. Aparentemente, não está sendo possível decriptografar usando storetype PKCS12. Por isso a minha desconfiança que o arquivo que você está passando como parâmetro não esteja no formato PKCS#12.

keytool -v -list -keystore <arquivo> -storetype PKCS12 

http://java.sun.com/javase/6/docs/technotes/tools/windows/keytool.html

estou passando esse arquivo:

certificado_rns.p12

não é esse?

qual o procedimento?..eu devo gerar o arquivo com o keytool e depois importar ele para a aplicação igual eu estou fazendo, ou tem algo a mais?

fui fazer um teste pelo q vc me disse, abri o prompt e fui fazendo…

[code]C:\Documents and Settings\Intel>cd C:\Documents and Settings\Intel\Desktop\Nova
pasta

C:\Documents and Settings\Intel\Desktop\Nova pasta>keytool -v -list -keystore ce
rtificado_rns.p12 -storetype PKCS12
Enter keystore password:
keytool error: java.io.IOException: parseAlgParameters failed: PBE AlgorithmPara
meters not available
java.io.IOException: parseAlgParameters failed: PBE AlgorithmParameters not avai
lable
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.parseAlgParameters(PKC
S12KeyStore.java:527)
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeySt
ore.java:1267)
at java.security.KeyStore.load(KeyStore.java:1185)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:711)
at sun.security.tools.KeyTool.run(KeyTool.java:171)
at sun.security.tools.KeyTool.main(KeyTool.java:165)
Caused by: java.security.NoSuchAlgorithmException: PBE AlgorithmParameters not a
vailable
at sun.security.jca.GetInstance.getInstance(GetInstance.java:142)
at java.security.Security.getImpl(Security.java:659)
at java.security.AlgorithmParameters.getInstance(AlgorithmParameters.jav
a:113)
at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.parseAlgParameters(PKC
S12KeyStore.java:523)
… 5 more

C:\Documents and Settings\Intel\Desktop\Nova pasta>[/code]

e na hora de gerar deu o msm erro q estava dando…será q é problema com o meu java instalado?..vc ja fez isso ai e deu certo?..tem algum jar adicional ou plugin para ler isso?

vlw

Duas possibilidades:
[list]Ou o arquivo não está no formato PKCS#12[/list]
Como foi gerado este arquivo? Se você não sabe o formato, sugiro você gerar novas chaves.

[list]Ou a sua instalação da JDK está com problema[/list]
Pegue este arquivo e faça o mesmo teste em outra máquina. Se funcionar é a instalação da JDK. Re-instale.

era problema no java msm…reinstalei e funcionou perfeitamente…

vlw a ajuda

Como esse não é um assunto nada trivial…vou postar aki o meu assinador usando PKCS12…para quem precisar ai um dia…

[code]package br.com.cienci.nfe.signature;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import javax.xml.crypto.;
import javax.xml.crypto.dsig.
;
import javax.xml.crypto.dom.;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.
;
import javax.xml.crypto.dsig.spec.;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.
;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;

/**
*

  • @author Ciro S. Santos
    */
    public class DigitalSignature {

    private static final String C14N_TRANSFORM_METHOD = “http://www.w3.org/TR/2001/REC-xml-c14n-20010315”;
    private static final String PROVIDER_CLASS_NAME = “org.jcp.xml.dsig.internal.dom.XMLDSigRI”;
    private static final String PROVIDER_NAME = “jsr105Provider”;

    public boolean sign(String xml, String certificado, String senha, String novoXml) {

     try {
         String providerName = System.getProperty(PROVIDER_NAME, PROVIDER_CLASS_NAME);  
    
         XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
                 (Provider) Class.forName(providerName).newInstance());
    
         ArrayList<Transform> transformList = new ArrayList<Transform>();
         TransformParameterSpec tps = null;
         Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, tps);
         Transform c14NTransform = fac.newTransform(C14N_TRANSFORM_METHOD, tps);
         transformList.add(envelopedTransform);
         transformList.add(c14NTransform);
    
         Reference ref = fac.newReference("",
                 fac.newDigestMethod(DigestMethod.SHA1, null),
                 transformList,
                 null,
                 null);
    
         SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
                 (C14NMethodParameterSpec) null),
                 fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                 Collections.singletonList(ref));           
    
         File file3 = new File("src\\securityResources");
         String path3 = file3.getAbsolutePath() + "\\" + certificado;
         KeyStore ks = KeyStore.getInstance("PKCS12");
         FileInputStream fis = new FileInputStream(path3);
         ks.load(fis, senha.toCharArray());
    
         Enumeration aliasesEnum = ks.aliases();
         String alias = "";
         while (aliasesEnum.hasMoreElements()) {
             alias = (String) aliasesEnum.nextElement();
             if (ks.isKeyEntry(alias)) {
                 break;
             }
         }
    
         KeyStore.PrivateKeyEntry keyEntry =
                 (KeyStore.PrivateKeyEntry) ks.getEntry(alias,
                 new KeyStore.PasswordProtection(senha.toCharArray()));
    
         X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
         KeyInfoFactory kif = fac.getKeyInfoFactory();
         List x509Content = new ArrayList();
         x509Content.add(cert);
         X509Data xd = kif.newX509Data(x509Content);
         KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));            
    
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         dbf.setNamespaceAware(true);
         File file = new File("src\\generatedXml");
         String path = file.getAbsolutePath() + "\\" + xml;
         Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(path));
    
         DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());
         XMLSignature signature = fac.newXMLSignature(si, ki);
         signature.sign(dsc);
    
         File file1 = new File("src\\signedXml");
         String path1 = file1.getAbsolutePath() + "\\" + novoXml;
         OutputStream os = new FileOutputStream(path1);
    
         TransformerFactory tf = TransformerFactory.newInstance();
         Transformer trans = tf.newTransformer();
         trans.transform(new DOMSource(doc), new StreamResult(os));
    
     } catch (ClassNotFoundException ex) {
         ex.printStackTrace();
         return false;
     } catch (InstantiationException ex) {
         ex.printStackTrace();
         return false;
     } catch (IllegalAccessException ex) {
         ex.printStackTrace();
         return false;
     } catch (TransformerConfigurationException ex) {
         ex.printStackTrace();
         return false;
     } catch (TransformerException ex) {
         ex.printStackTrace();
         return false;
     } catch (MarshalException ex) {
         ex.printStackTrace();
         return false;
     } catch (XMLSignatureException ex) {
         ex.printStackTrace();
         return false;
     } catch (UnrecoverableEntryException ex) {
         ex.printStackTrace();
         return false;
     } catch (CertificateException ex) {
         ex.printStackTrace();
         return false;
     } catch (KeyStoreException ex) {
         ex.printStackTrace();
         return false;
     } catch (InvalidAlgorithmParameterException ex) {
         ex.printStackTrace();
         return false;
     } catch (NoSuchAlgorithmException ex) {
         ex.printStackTrace();
         return false;
     } catch (ParserConfigurationException ex) {
         ex.printStackTrace();
         return false;
     } catch (SAXException ex) {
         ex.printStackTrace();
         return false;
     } catch (IOException ex) {            
         ex.printStackTrace();
         return false;
     }
     return true;
    

    }
    }
    [/code]

flw, um abraço!