[quote=jluizsc]Ola Pessoal
Eu usei o mesmo codigo postado aqui no grupo
e adicionei um codigo o codigo X509 no projeto (ou na pasta)
somente esses dois jah funcionou
usar: Assinador.assinar( … )
segue os dois arquivos *.java na sequencia
Assinador.java
/*
- To change this template, choose Tools | Templates
- and open the template in the editor.
*/
package assinadornfe01;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
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.dom.DOMValidateContext;
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.Element;
import org.w3c.dom.NodeList;
//import sun.misc.BASE64Encoder;
import java.util.Enumeration;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.security.PrivateKey;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import javax.swing.JOptionPane;
import AssinadorNFE.X509KeySelector;
public class Assinador
{
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 void assinar(String caminhoXml, String caminhoCertificado, String senha, String caminhoXmlNovo, String tipo) throws Exception
{
// tipo
// '1' - NFE
// '2' - CANCELAMENTO
// '3' - INUTILIZACAO
//
String tag = "";
if(tipo.equals("1"))
tag = "infNFe";
else if (tipo.equals("2"))
tag = "infCanc";
else if (tipo.equals("3"))
tag = "infInut";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document docs = builder.parse(new File(caminhoXml));
//Document docs = builder.parse(new File("c:/xml/430802017886010001735500000000010000030371-nfe.xml"));
// Obtem elemento do documento a ser assinado, será criado uma
// REFERENCE para o mesmo
NodeList elements = docs.getElementsByTagName(tag);
Element el = (Element) elements.item(0);
String id = el.getAttribute("Id");
//System.out.println(id);
// Create a DOM XMLSignatureFactory that will be used to
// generate the enveloped signature.
String providerName = System.getProperty(PROVIDER_NAME, PROVIDER_CLASS_NAME);
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", (Provider) Class.forName(providerName).newInstance());
//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);
// 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!");
}
}
public static void main(String[] args) throws Exception {
if(args.length != 5)
{
//JOptionPane.showMessageDialog(null, "São esperados 5 parâmetros!", "Atenção", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Sao esperados 5 parametros!");
return;
}
String caminhoXml = args[0];
String caminhoCertificado = args[1];
String senha = args[2];
String arquivoXmlNovo = args[3];
String tipo = args[4];
File file = new File(caminhoXml);
if(!file.exists())
{
//JOptionPane.showMessageDialog(null, "Arquivo " + caminhoXml + " não encontrado!", "Atenção", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Arquivo " + caminhoXml + " não encontrado!");
return;
}
file = new File(caminhoCertificado);
if(!file.exists())
{
//JOptionPane.showMessageDialog(null, "Arquivo " + caminhoCertificado + " não encontrado!", "Atenção", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Arquivo " + caminhoCertificado + " não encontrado!");
return;
}
try
{
Assinador t = new Assinador();
t.assinar(caminhoXml, caminhoCertificado, senha, arquivoXmlNovo, tipo);
//JOptionPane.showMessageDialog(null, "Arquivo xml assinado com sucesso!", "Atenção", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Arquivo xml assinado com sucesso" + caminhoXml + "!");
}
catch(Exception e)
{
//JOptionPane.showMessageDialog(null, "Erro ao tentar assinar arquivo xml! \n\n" + e.toString(), "Atenção", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Erro ao tentar assinar arquivo xml! \n\n" + e.toString());
}
}
}
X509KeySelector.java
package AssinadorNFE;
import java.io.InputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertSelector;
import java.security.cert.X509Certificate;
import java.security.cert.X509CertSelector;
import java.util.Enumeration;
import java.util.Iterator;
import javax.security.auth.x500.X500Principal;
import javax.xml.crypto.;
import javax.xml.crypto.dsig.;
import javax.xml.crypto.dom.;
import javax.xml.crypto.dsig.keyinfo.;
/**
-
A KeySelector
that returns {@link PublicKey}s of trusted
-
{@link X509Certificate}s stored in a {@link KeyStore}.
-
-
This KeySelector
uses the specified KeyStore
-
to find a trusted X509Certificate
that matches information
-
specified in the {@link KeyInfo} passed to the {@link #select} method.
-
The public key from the first match is returned. If no match,
-
null
is returned. See the select
method for more
-
information.
-
-
NOTE!: This X509KeySelector requires J2SE 1.4 because it uses the
-
java.security.cert.X509CertSelector & javax.security.auth.x500.X500Principal
-
classes to parse X.500 DNs and match on certificate attributes.
-
-
@author Sean Mullan
*/
public class X509KeySelector extends KeySelector {
private KeyStore ks;
/**
- Creates an
X509KeySelector
.
-
-
@param keyStore the keystore
-
@throws KeyStoreException if the keystore has not been initialized
-
@throws NullPointerException if
keyStore
is
-
null
*/
public X509KeySelector(KeyStore keyStore) throws KeyStoreException {
if (keyStore == null) {
throw new NullPointerException(“keyStore is null”);
}
this.ks = keyStore;
// test to see if KeyStore has been initialized
this.ks.size();
}
/**
SignatureMethod sm = (SignatureMethod) method;
try {
// return null if keyinfo is null or keystore is empty
if (keyInfo == null || ks.size() == 0) {
return new SimpleKeySelectorResult(null);
}
// Iterate through KeyInfo types
Iterator i = keyInfo.getContent().iterator();
while (i.hasNext()) {
XMLStructure kiType = (XMLStructure) i.next();
// check X509Data
if (kiType instanceof X509Data) {
X509Data xd = (X509Data) kiType;
KeySelectorResult ksr = x509DataSelect(xd, sm);
if (ksr != null) {
return ksr;
}
// check KeyName
} else if (kiType instanceof KeyName) {
KeyName kn = (KeyName) kiType;
Certificate cert = ks.getCertificate(kn.getName());
if (cert != null && algEquals(sm.getAlgorithm(),
cert.getPublicKey().getAlgorithm())) {
return new SimpleKeySelectorResult(cert.getPublicKey());
}
// check RetrievalMethod
} else if (kiType instanceof RetrievalMethod) {
RetrievalMethod rm = (RetrievalMethod) kiType;
try {
KeySelectorResult ksr = null;
if (rm.getType().equals
(X509Data.RAW_X509_CERTIFICATE_TYPE)) {
OctetStreamData data = (OctetStreamData)
rm.dereference(context);
CertificateFactory cf =
CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)
cf.generateCertificate(data.getOctetStream());
ksr = certSelect(cert, sm);
} else if (rm.getType().equals(X509Data.TYPE)) {
NodeSetData nd = (NodeSetData)
rm.dereference(context);
// convert nd to X509Data
// ksr = x509DataSelect(xd, sm);
} else {
// skip; keyinfo type is not supported
continue;
}
if (ksr != null) {
return ksr;
}
} catch (Exception e) {
throw new KeySelectorException(e);
}
}
}
} catch (KeyStoreException kse) {
// throw exception if keystore is uninitialized
throw new KeySelectorException(kse);
}
// return null since no match could be found
return new SimpleKeySelectorResult(null);
}
/**
- Searches the specified keystore for a certificate that matches the
- criteria specified in the CertSelector.
-
-
@return a KeySelectorResult containing the cert’s public key if there
- is a match; otherwise null
*/
private KeySelectorResult keyStoreSelect(CertSelector cs)
throws KeyStoreException {
Enumeration aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = (String) aliases.nextElement();
Certificate cert = ks.getCertificate(alias);
if (cert != null && cs.match(cert)) {
return new SimpleKeySelectorResult(cert.getPublicKey());
}
}
return null;
}
/**
- Searches the specified keystore for a certificate that matches the
- specified X509Certificate and contains a public key that is compatible
- with the specified SignatureMethod.
-
-
@return a KeySelectorResult containing the cert’s public key if there
- is a match; otherwise null
*/
private KeySelectorResult certSelect(X509Certificate xcert,
SignatureMethod sm) throws KeyStoreException {
// skip non-signer certs
boolean[] keyUsage = xcert.getKeyUsage();
if (keyUsage[0] == false) {
return null;
}
String alias = ks.getCertificateAlias(xcert);
if (alias != null) {
PublicKey pk = ks.getCertificate(alias).getPublicKey();
// make sure algorithm is compatible with method
if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
return new SimpleKeySelectorResult(pk);
}
}
return null;
}
/**
- Returns an OID of a public-key algorithm compatible with the specified
- signature algorithm URI.
*/
private String getPKAlgorithmOID(String algURI) {
if (algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
return “1.2.840.10040.4.1”;
} else if (algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1)) {
return “1.2.840.113549.1.1”;
} else {
return null;
}
}
/**
- A simple KeySelectorResult containing a public key.
*/
private static class SimpleKeySelectorResult implements KeySelectorResult {
private final Key key;
SimpleKeySelectorResult(Key key) { this.key = key; }
public Key getKey() { return key; }
}
/**
- Checks if a JCA/JCE public key algorithm name is compatible with
- the specified signature algorithm URI.
*/
//@@@FIXME: this should also work for key types other than DSA/RSA
private boolean algEquals(String algURI, String algName) {
if (algName.equalsIgnoreCase(“DSA”) &&
algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) {
return true;
} else if (algName.equalsIgnoreCase(“RSA”) &&
algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1)) {
return true;
} else {
return false;
}
}
/**
- Searches the specified keystore for a certificate that matches an
- entry of the specified X509Data and contains a public key that is
- compatible with the specified SignatureMethod.
-
-
@return a KeySelectorResult containing the cert’s public key if there
- is a match; otherwise null
*/
private KeySelectorResult x509DataSelect(X509Data xd, SignatureMethod sm)
throws KeyStoreException, KeySelectorException {
// convert signature algorithm to compatible public-key alg OID
String algOID = getPKAlgorithmOID(sm.getAlgorithm());
KeySelectorResult ksr = null;
Iterator xi = xd.getContent().iterator();
while (xi.hasNext()) {
ksr = null;
Object o = xi.next();
// check X509Certificate
if (o instanceof X509Certificate) {
X509Certificate xcert = (X509Certificate) o;
ksr = certSelect(xcert, sm);
// check X509IssuerSerial
} else if (o instanceof X509IssuerSerial) {
X509IssuerSerial xis = (X509IssuerSerial) o;
X509CertSelector xcs = new X509CertSelector();
try {
xcs.setSubjectPublicKeyAlgID(algOID);
xcs.setSerialNumber(xis.getSerialNumber());
xcs.setIssuer(new X500Principal
(xis.getIssuerName()).getName());
} catch (IOException ioe) {
throw new KeySelectorException(ioe);
}
ksr = keyStoreSelect(xcs);
// check X509SubjectName
} else if (o instanceof String) {
String sn = (String) o;
X509CertSelector xcs = new X509CertSelector();
try {
xcs.setSubjectPublicKeyAlgID(algOID);
xcs.setSubject(new X500Principal(sn).getName());
} catch (IOException ioe) {
throw new KeySelectorException(ioe);
}
ksr = keyStoreSelect(xcs);
// check X509SKI
} else if (o instanceof byte[]) {
byte[] ski = (byte[]) o;
X509CertSelector xcs = new X509CertSelector();
try {
xcs.setSubjectPublicKeyAlgID(algOID);
} catch (IOException ioe) {
throw new KeySelectorException(ioe);
}
// DER-encode ski - required by X509CertSelector
byte[] encodedSki = new byte[ski.length+2];
encodedSki[0] = 0x04; // OCTET STRING tag value
encodedSki[1] = (byte) ski.length; // length
System.arraycopy(ski, 0, encodedSki, 2, ski.length);
xcs.setSubjectKeyIdentifier(encodedSki);
ksr = keyStoreSelect(xcs);
// check X509CRL
// not supported: should use CertPath API
} else {
// skip all other entries
continue;
}
if (ksr != null) {
return ksr;
}
}
return null;
}
}
–
Joao Luiz - Linux user #159951
WEB : http://site.pop.com.br/jluizsc
my space : http://www.myspace.com/jluizsc
GRATIS eh POUCO: http://br.geocities.com/jluizsc (explicacoes orolix)
GRATIS eh POUCO 2 : http://www.crescenet.dahora.net (explicacoes crescenet)
[/quote]
Usei seu código para assinar um lote de notas fiscais mas ele assinou a tag enviNFe e não cada NFe.
Veja a imagem do XML (no NB):

O que tenho que mudar para ele assinar a tab NFe?