Firma digitale con openssl

Buongiorno @giulio Guerriero, il problema non è OpenSSL di per sé. Noi in un vecchio progetto (2001) nella società dove lavoro, ne abbiamo fatto un gran uso, è uno strumento fantastico, ma prevede “di suo” tutte le chiamate con chiavi esterne e questo non è realizzabile perché la normativa non lo consente. Le chiavi devono sempre essere mantenute all’interno di un HSM (Hardware Security Module) che sia un pendrive oppure una SmartCard, poco importa.
La modalità d’uso, per confortare @ettoremazza, è poco importante: ok a tenere il dispositivo sicuro sempre connesso.
Ciò che serve è quindi un modo per interfacciare OpenSSL con le librerie (se disponibili) che consentano di dialogare con le chiavi presenti nei certificati a bordo del dispositivo sicuro.
Purtroppo OpenSSL è veramente un oggetto estremamente complesso, così tanto che ho sentito vi sono dei fork del progetto al fine di ridurre il numero di linee di codice. Interfacciarlo con API di un fornitore di qualche dispositivo sicuro non è cosa banale, né economico potrà essere poter disporre di tali API a meno che, come facemmo noi insieme all’Agenzia delle Entrate, non si richiedesse allo stesso di fornire le librerie in grado di dialogare con il dispositivo con licenza limitata a tale progetto. Il lavoro è comunque non semplice, ma realizzabile per chi conosca bene OpenSSL ed il linguaggio con cui è scritto.
Chissà per la Firma digitale delle fatture, che tipo di accordo è stato fatto tra il Governo ed i cittadini. Io ignoro totalmente l’argomento, quindi di più non ti so aiutare.
Luca

Facciamo un po’ di chiarezza. La firma con la CIE è una firma elettronica avanzata ai sensi dell’art. 61 del DPCM 22 febbraio 2013 (Regole tecniche sulla firma). Quindi non è valida per le fatture che richiedono una firma elettronica qualificata o digitale (sono oramai equivalenti, ma non per il CAD). Una sottoscrizione con procedura automatica (art. 35, comma 3 del CAD) richiede una particolare procedura e il certificato del titolare deve essere specifico per questo tipo di procedura (contiene una particolare estensione). Un certificato su chiavetta USB non è per procedura automatica. Il certificato del titolare è estraibile dalla chiavetta USB quello che per ovvi motivi di sicurezza è la chiave privata del titolare stesso associata alla chiave pubblica contenuta nel certificato. La chiave pubblica viene utilizzata per la verifica della firma.
La chiavetta può essere usata per la firma di flussi di documenti ma è ovviamente lenta (altrimenti nessuno utilizzerebbe la firma con procedura automatica) e su numeri elevati di documenti da firmare “non va bene”. Si possono firmare n documenti usando la tecnica del libro firma ovvero i documenti vengono inviati alla firma da un applicativo che consente anche di digitare una sola volta il PIN. Questa non è una firma automatica è una firma e basta. La firma remota è definita sempre nel DPCM 22 febbraio 2013 ed è relativa all’utilizzo di un dispositivo di firma remoto denominato HSM (Hardware Security Module). Nulla a che vedere con la chiavetta che è evidentemente sotto il controllo esclusivo del titolare. La sintesi porta a qualche leggera imprecisione ma spero di aver spiegato.

2 Mi Piace

In realtà non ho capito granchè!!!
Quello che so per certo è che Sogei mi ha rilasciato un certificato di firma con cui firmare il pacchetto di fatture che invio a loro, e questo posso farlo tranquillamente con OPENSSL.

All’interno del pacchetto devo firmare le fatture per la PA (obbligatoriamente) e le fatture B2B (facoltativo) con un certificato di firma diverso da quello usato per l’invio.

Ora sono costretto ad utilizzare la mia chiavetta USB della Camera di commercio con Dike Lite che c’è all’interno per firmare tutte le fatture. Devo mettere il PIN una volta sola ma sono costretto a farlo io a mano ogni volta.

Possibile che non esiste un metodo per togliersi questa schiavitù?!? E che non costi 10.000 euro!

Si direbbe che quello di SOGEI e’ un certifiato di firma ma non una firma digitale. Nel senso, lo riconsoce valido SOGEI nell’ambito della transazione nel sistema FatturaPA ma non ha niente a che vedere con una firma digitale. Quest’ultima si basa sulla stessa identica tecnica/tecnologia (crittografia a chiavi asimmetriche applicata all’impronta digitale dell’oggetto) ma si differenzia per le condizini organizzative di contorno, quali per esempio che e’ rilasciata da un certificatore autorizzato, che risiede su quei dispostivi sicuri di cui sopra dai quali non si puo’ estrarre ecc.

Se il problema e’ fimare digitalmente piu’ file (n qusto caso gli XML delle fatture) in un colpo solo e attualmente si usa Dike Lite e quindi va bene lancaire l’operazione manualmente, ci sono vari software di firma/verifica di firma che consentono di firmare piu’ file. Visto che la lista dei software “buoni” per firmare e verificare è pubblica e pubblica su AgID (altro elemento organizzativo di contorno che caratterizza la firma digitale italiana), niente di male a citarli per nome: Aruba Sign consente firma di piu’ file insieme (non so se anche in modalità XAdES), Actalis File Protector anche (stesso dubbio su XAdEs e, tempo fa, mi sembra di non averlo piu’ visto in lista). Ce ne saranno anche altri (fra cui la versione a pagamento di Dike). Niente vieta che ne esistano anche di utilizzabili da riga di comando e quindi gestibili con qualche script, oppure con API a disposizone, come spiegava qualcuno: sembra che quello che ti serve non sia estrarre il certificato (che è impossibile) ma usare il certificato contenuto nel dispositivo in maniera piu’ agile.

Bene, l’importante e’ agire con consapevolezza e avere argomenti a suffragio delle proprie scelte.

@frantheman stai a fa’ un macello però… quello della SOGEI è un certificato di firma a tutti gli effetti, ma non è quello il problema. A me servirebbe un certificato di firma da usare con OPENSSL proprio perchè non voglio star lì a inserire il PIN ogni volta.

Macello? Non mi sembra! E perche’ mai?

E’ stato sottolineato anche da fonti piu’ autorevoli di me che e’ firma digitale solo cio’ che sta in un dispositivo sicuro.
Di conseguenza: quello di SOGEI non è un certificato di firma digitale (EDIT) e non puoi fare firme digitali con certificati esterni a un dispositivo, quindi quello che chiedi non e’ possibile.

Per la precisione, quello di SOGEI è un certificato di firma, sebbene non valido ai fini del CAD.

@frantheman non credo che software come Fatture in Cloud hanno una chiavetta USB collegata al computer per firmare milioni di fatture e ho già avuto delle offerte da Aruba (per esempio) per fare quello che dico. Perciò è assolutamente falso quello che dici.

vabbe’, parliamo lingue diverse. mi spiace. evito di aggiungere ulteriori falsita’.
risposte e indicazioni sullo stato dell’arte sono state fornite.

2 Mi Piace

@p15 Di queste cose abbiamo già discusso in altri thread in questo forum. Te li sei letti?
Da quello che ricordo con le ultime versioni di openssl, è possibile firmare le fatture usando la chiavetta. Vedi qui:

Volendo puoi automatizzare la cosa memorizzando il PIN sul server (se usi OpenSSL a riga di comando, lo devi passare tra i parametri). Non entro nel merito sul fatto se sia legale o meno.

I certificati dell’Agenzia delle Entrate (incluso quello rilasciato per il canale SdI) possono essere usati per firmare le fatture che verranno accettate dal SdI, ma non si tratta di una “firma elettronica qualificata” come richiesto per le fatture PA. C’è anche scritto nelle specifiche tecniche.

Sulla domanda “come fanno Fatture in Cloud e gli altri grossi fornitori di servizi di fatturazione?”: ovviamente usano servizi (o propri sistemi, se sono accreditati) per la firma automatica. L’unico problema è che questi servizi costano sui 2000€/anno circa (questo era il prezzo citato nell’altro thread) e convengono solo se hai volumi abbastanza grandi da giustificarne il costo.

1 Mi Piace

penso sia interessante la soluzione proposta da Vladan Bato
io personalmente utilizzo la libreira bouncycastle https://www.bouncycastle.org/
dal momento che per il mio gestionale utilizzo il canale archivium, fino ad oggi non ho avuto la necessità di firmare le fatture.
la libreria bouncycastle la utilizzo per togliere la firma nelle fatture in arrivo in modo che il gestionale possa visualizzare il contenuto della fattura senza mandare nel pallone le librerie xml.
se a qualcuno puo interessare:

package main;

import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.util.Collection;
import java.util.Iterator;

import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.util.Store;

public class SIgnature {

	public static void main(String[] args) {
		if(args.length>1) {
			String command = args[0];
			String filenameimput = args[1];
			String inExt = args[2];
			String outExt = args[3];
			removeSignature(filenameimput,inExt,outExt );
		}
	}

	private static void removeSignature(String docfile, String inExt, String outExt) {
		String nosigned = "";
		try {
			// Loading the file first
			File f = new File(docfile);
			byte[] buffer = new byte[(int) f.length()];
			DataInputStream in = new DataInputStream(new FileInputStream(f));
			in.readFully(buffer);
			in.close();

			//Corresponding class of signed_data is CMSSignedData
			CMSSignedData signature = new CMSSignedData(buffer);
			Store cs = signature.getCertificates();
		   SignerInformationStore signers = signature.getSignerInfos();
		   Collection c = signers.getSigners();
		   Iterator it = c.iterator();

		   //the following array will contain the content of xml document
		   byte[] data = null;
		   while (it.hasNext()) {
		        SignerInformation signer = (SignerInformation) it.next();
		        Collection certCollection = cs.getMatches(signer.getSID());
		        Iterator certIt = certCollection.iterator();
		        X509CertificateHolder cert = (X509CertificateHolder) certIt.next();

		        CMSProcessable sc = signature.getSignedContent();
		        data = (byte[]) sc.getContent();
		    }
			nosigned = new String(data);
			//return nosigned;
			BufferedWriter writer = new BufferedWriter(new FileWriter(docfile.replaceAll(inExt,outExt)));
			writer.write(nosigned);
			writer.close();
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
}