gine ha scritto:
Paolo64 ha scritto:
Per il resto ho molti dubbi, e sono anch'io inchiodato a questo punto, in quanto la risposta di tutte le prove di invio che ho fatto è sempre: 406 xml non conforme
Occhio che l'algoritmo di canocalizzazione la cui descrizione è descritta qui:
https://www.w3.org/TR/2001/REC-xml-c14n-20010315#Examples
prevede anche che lo xml sia formattato con spazi, tab, in una maniera precisa. Quindi se tu stai implementando questa procedura senza una libreria specifica stacci attento altrimenti il contenuto è completo e posizionato nei posti correttamente ma ci sono degli spazi in giro o la forma non è quella prevista dall'algoritmo di canocalizzazione che si deve usare.
Gine ciao
Grazie dell'info. Proverò a rivedere l'xml.
Volevo chiederti: tu come fai a firmare il file ? Usi una libreria proprietaria come Jeremiah o usi altro ?
Io sto provando con il codice Java di esempio che c'è in fondo sulla pagina: Utilizzare Api Rest
Il codice è questo:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Provider;
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.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.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;
public class Firma {
public static final String SHA256_RSA_SIGNATURE_ALGORITHM = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
//originale=String p12file = "path_certificato_di_firma.p12";
String p12file = "c:/Users/PAOLO2/Desktop/VendingMachine/certificato38380.pfx";
String p12pass = "7264809992";
//String infile = "path_file_da_firmare.xml";
//String signedfile = "path_file_firmato.xml";
String infile = "c:/Users/PAOLO2/Desktop/VendingMachine/RichiestaCertificatoDispositivo_img.xml";
String signedfile = "c:/Users/PAOLO2/Desktop/VendingMachine/RichiestaCertificatoDispositivo_Firmato.xml";
Provider provider = null;
/*
provider = xml.XMLUtils.getXmlDsigProvider();
System.out.println("XML provider: " + provider);
*/
X509Certificate signerCert = null;
PrivateKey key = null;
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream(p12file), p12pass.toCharArray());
Enumeration<String> en = ks.aliases();
while (en.hasMoreElements()) {
String alias = (String) en.nextElement();
if (ks.isKeyEntry(alias)) {
signerCert = (X509Certificate) ks.getCertificate(alias);
key = (PrivateKey) ks.getKey(alias, p12pass.toCharArray());
break;
}
}
if (signerCert == null || key == null) {
throw new Exception("Key or Certificate not found!!");
}
// Create a DOM XMLSignatureFactory that will be used to generate the
// enveloped signature
XMLSignatureFactory fac;
if (provider == null) {
fac = XMLSignatureFactory.getInstance("DOM");
} else {
fac = XMLSignatureFactory.getInstance("DOM", provider);
}
// Create a Reference to the enveloped document (in this case we are
// signing the whole document, so a URI of "" signifies that) and
// also specify the SHA1 digest algorithm and the ENVELOPED Transform.
Reference ref = fac.newReference(
"",
fac.newDigestMethod(DigestMethod.SHA256, null),
Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
null,
null);
// Create the SignedInfo
SignedInfo si = fac.newSignedInfo(
fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null),
fac.newSignatureMethod(SHA256_RSA_SIGNATURE_ALGORITHM, null),
Collections.singletonList(ref));
KeyInfoFactory kif;
if (provider == null) {
kif = KeyInfoFactory.getInstance("DOM");
} else {
kif = KeyInfoFactory.getInstance("DOM", provider);
}
// Aggiunta del certificato del firmatario in KeyInfo
List x509DataContent = new ArrayList();
x509DataContent.add(signerCert);
X509Data x509Data = kif.newX509Data(x509DataContent);
List keyInfoContent = new ArrayList();
keyInfoContent.add(x509Data);
KeyInfo ki = kif.newKeyInfo(keyInfoContent);
// Instantiate the document to be signed
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(true);
// default false
// dbf.setIgnoringElementContentWhitespace(true);
// default true
// dbf.setExpandEntityReferences(false);
Document doc = null;
doc = dbf.newDocumentBuilder().parse(new FileInputStream(infile));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's parent element
DOMSignContext dsc = new DOMSignContext(key, doc.getDocumentElement());
dsc.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
dsc.putNamespacePrefix(XMLSignature.XMLNS, "ds");
// 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;
os = new FileOutputStream(signedfile);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
System.out.println("File " + signedfile + " firmato.");
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Il codice funziona; viene sempre fuori il file firmato, ma quando lo trasmetto mi dà sempre l'inesorabile 406 non conforme.
Un ulteriore dubbio è questo: quando generi il CSR
io uso questi due passaggi:
• Il primo passo consiste nella Generazione della chiave RSA mediante il comando:
openssl genrsa –out mykey.key 2048
• Il secondo passo consiste nella Generazione della CSR mediante il comando:
openssl req -new -key mykey.key -out mycsr.csr
Country Name (2 letter code) [AU]:IT
State or Province Name (full name) [Some-State]:Provincia
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Nome Azienda
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:AAABBB99C23xxxxZ
Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate reque
A challenge password []:
An optional company name []:
Di questi campi io ho usato:
COUNTRY NAME: IT
PROVINCE: TREVISO
LOCALITY NAME: nulla
ORGANIZATION NAME: LA PARTITA IVA O IL CODICE FISCALE ??
COMMON NAME: IMEI DEL CELLULARE
EMAIL ADDRES: nulla
A CHALLENGE PW: NULLA O BISOGNA METTERE UNA PASSWORD ??
A OPT COMP.NAME: nulla
Tu come hai fatto ??
Ciao
Paolo