DAS Elettronico

Sto avendo lo stesso problema… Qualche novità?

Devi uscire e rientrare tramite SPID affinchè compaia la scritta “Gestione Certificati” nella sezione “Interattivi”. Per generare il certificato in ambiente Ufficiale è immediato, in ambiente di Prova c’è da aspettare 24 ore. Per generarlo, segui le istruzioni per il programma XCA (più semplice rispetto ai comandi DOS) che trovi sempre nella sezione Gestione Certificato.

Ancora saluti. Giuseppe.
Ho risolto il problema. Mettevo una riga sul trasporto che non andava e che non ho riportato nel mex precedente. Ora ho un problema con la firma. Firmando con il metodo .NET che riporto qui sotto, col certificato che uso (sempre con l’app commerciale che ho dovuto comprare) mi viene restituito un errore 5-Messaggio non firmato. Puoi dirmi cosa hai usato per firmare?

======================================================================
Dim xmlDoc As New XmlDocument()
xmlDoc.Load(nomeFileInput)
Dim csPars As New CspParameters()
csPars.KeyContainerName = “BDLNFD45L47C708J-001”
Dim rsaKey As New RSACryptoServiceProvider(csPars)
Dim sXml As New SignedXml(xmlDoc)
sXml.SigningKey = rsaKey
Dim ref As New Reference()
ref.Uri = “”
Dim env As New XmlDsigEnvelopedSignatureTransform()
ref.AddTransform(env)
sXml.AddReference(ref)
sXml.ComputeSignature()
Dim firma As XmlElement = sXml.GetXml
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(firma, True))
nomeFileInput += “.p7m”
xmlDoc.Save(nomeFileInput)

Eccomi ancora.
Ho scaricato la dll FirmaXaDesNet ed ora il messaggio che ottengo è differente, ovvero “Firma non riconosciuta”. Il mio dubbio è che la cifratura NON avvenga con l’algoritmo SHA256. Allego il codice usato per firmare

========================================================
Imports FirmaXadesNet.Signature.Parameters
Imports FirmaXadesNet

Class FirmaXml
Dim firmaDes As New FirmaXaDes
With firmaDes
.parametros.SignaturePolicyInfo = New SignaturePolicyInfo()
.parametros.SignaturePolicyInfo.PolicyIdentifier = “https://tribunet.hacienda.go.cr/docs/esquemas/2016/v4.1/Resolucion_Comprobantes_Electronicos_DGT-R-48-2016.pdf
.parametros.SignaturePolicyInfo.PolicyHash = “Ohixl6upD6av8N7pEvDABhEL6hM=”
.parametros.SignaturePackaging = SignaturePackaging.ENVELOPED
.parametros.
.parametros.DataFormat = New DataFormat()
Dim pf = CERTLAVORO.LastIndexOf("")
Dim certFirma As X509Certificate2 = New X509Certificate2(CERTLAVORO.Substring(0, pf + 1) + “BDLNFD45L47C708J.p12”, “LI8F6TQO”)
.parametros.Signer = New FirmaXadesNet.Crypto.Signer(certFirma)
Dim fs As FileStream = New FileStream(nomeFileInput, FileMode.Open)
Dim docFirmado As FirmaXadesNet.Signature.SignatureDocument = .xadesService.Sign(fs, .parametros)
fs.Close()
docFirmado.Save(nomeFileInput + “.p7m”)
End With
End Class

Imports FirmaXadesNet
Imports FirmaXadesNet.Signature.Parameters
'Imports System.Deployment.Internal.CodeSigning

Public Class FirmaXaDes
Public xadesService As XadesService = New XadesService
Public parametros As SignatureParameters = New SignatureParameters
End Class

Buongiorno Giacomo,
io invece purtroppo usando gli esempi dei FirmaXadesNet 4.5 riesco a mandare il file, ma mi da “Firma non riconosciuta”. Puoi darmi delle dritte su come usare la dll in modo corretto?

Saverio Tedeschi

================================================================
Imports FirmaXadesNet
Imports FirmaXadesNet.Signature.Parameters
'Imports System.Deployment.Internal.CodeSigning

Public Class FirmaXaDes
Public xadesService As XadesService = New XadesService
Public parametros As SignatureParameters = New SignatureParameters
End Class

Public Class InvioTest
Dim firmaDes As New FirmaXaDes
With firmaDes
.parametros.SignaturePolicyInfo = New SignaturePolicyInfo()
.parametros.SignaturePolicyInfo.PolicyIdentifier = “https://tribunet.hacienda.go.cr/docs/esquemas/2016/v4.1/Resolucion_Comprobantes_Electronicos_DGT-R-48-2016.pdf
.parametros.SignaturePolicyInfo.PolicyHash = “Ohixl6upD6av8N7pEvDABhEL6hM=”
.parametros.SignaturePackaging = SignaturePackaging.ENVELOPED
.parametros.DataFormat = New DataFormat()
Dim pf = CERTLAVORO.LastIndexOf("")
Dim certFirma As X509Certificate2 = New X509Certificate2(CERTLAVORO.Substring(0, pf + 1) + “BDLNFD45L47C708J.p12”, “LI8F6TQO”)
.parametros.Signer = New FirmaXadesNet.Crypto.Signer(certFirma)
Dim fs As FileStream = New FileStream(nomeFileInput, FileMode.Open)
Dim docFirmado As FirmaXadesNet.Signature.SignatureDocument = .xadesService.Sign(fs, .parametros)
fs.Close()
docFirmado.Save(nomeFileInput + “.p7m”)
End With
End Class

Ciao Saverio, per effettuare la firma utilizzo la libreria a pagamento Chilkat. Ho provato ad utilizzare FirmaXades, ma non mi ha mai funzionato. L’esempio indicato da Giacomo non l’ho provato perchè avevo già adottato Chilkat e quindi non mi ci sono dedicato. Molto probabilmente in fase di firma la tua procedura va a prendere un certificato non adatto che quindi non effettua la firma.

Prova, prima di firmare, a esportare i dati in formato XML, e fai la stessa operazione dopo la firma. Dovresti trovare, in coda al file, la firma “in chiaro” (ovviamente criptata, ma comunque visibile). Se i file sono uguali, significa che devi modificare qualcosa.

Grazie. Ma gli esempi che fornisce chilkat sono piuttosto generici. Puoi dirmi da che esempio sei partito o come hai configurato chilkat?

Scusami, non ho le notifiche e ho visto solo oggi la tua richiesta, nel sommario settimanale :slightly_smiling_face:

ecco il mio codice:

Metodi utilizzati per impostare i parametri di firma e permettere all’utente di scegliere il certificato:

   private SignatureParameters OttieniParametriFirma()
    {
        SignatureParameters parametros = new SignatureParameters();
        parametros.SignatureMethod = SignatureMethod.RSAwithSHA512;
        parametros.SigningDate = DateTime.Now;

        // Test SignatureCommitment
        var sc = new SignatureCommitment(SignatureCommitmentType.ProofOfOrigin);
        parametros.SignatureCommitments.Add(sc);

        return parametros;
    }
             
public static X509Certificate2 SelectCertificate(string message = null, 
                string title = null)
    {
        X509Certificate2 cert = null;

        try
        {
            // Open the store of personal certificates.
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

            X509Certificate2Collection collection = store.Certificates;
            X509Certificate2Collection fcollection = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);

            if (string.IsNullOrEmpty(message))
            {
                message = "Seleziona un certificato.";
            }

            if (string.IsNullOrEmpty(title))
            {
                title = "Firmare File";
            }

            X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, title, message, X509SelectionFlag.SingleSelection);

            if (scollection != null && scollection.Count == 1)
            {
                cert = scollection[0];

                if (cert.HasPrivateKey == false)
                {
                    throw new Exception("Il Certificato non ha una chiave privata associata.");
                }
            }

            store.Close();
        }
        catch (Exception ex)
        {
            // Thx @rasputino
            throw new Exception("Non è stato possibile ottenere la chiave privata.", ex);
        }

        return cert;
    }

Frammento di codice dove firmo il file:

            SignatureDocument _signatureDocument;

            XadesService xadesService = new XadesService();
            SignatureParameters parametros = OttieniParametriFirma();

            parametros.SignaturePackaging = SignaturePackaging.ENVELOPED;
            var cert = SelectCertificate(); // CertUtil.SelectCertificate();
            if (cert == null) { return false; }
            using (parametros.Signer = new Signer(cert))
            {
                using (FileStream fs = new FileStream(_dasEnv.DasXmlFIleName(das.NumeroLocaleDas), FileMode.Open))
                {
                    _signatureDocument = xadesService.Sign(fs, parametros);
                }

            }
            _signatureDocument.Save(_dasEnv.DasXmlFIleNameSigned(das.NumeroLocaleDas));

Grazie Giacomo.
Mi sembra che sei uno dei pochi che usa .NET, spero che tu mi possa ancora aiutare. Sono riuscito ad inviare il messaggio richiediDE801, ma il messaggio che mi ritorna è sempre privo della parte dati, che dovrebbe contenere il file pdf col documento da stampare. C’è da modificare qualcosa nella classe che gestisce il binding o cosa? Purtroppo SOGEI al riguardo è molto abbottonata,

Grazie Giuseppe.
Risolti i problemi con la firma (di sicurezza più che di procedura, visto che la firma dell’amministratore potrebbe esser usata per operazioni anche pericolose), usando un programma commerciale di firma remota, intestato ad un delegato della ditta “speditrice”. Ora però ho il problema che non riesco a recuperare il file pdf che contiene il glifo, che dovrebbe essere nella risposta al DE815 o successivamente al DE801. usando i webServices creati da .NET ottengo solo una risposta col campo data sempre a Nothing. Puoi aiutarmi in questo? come hai fatto? A questo punto invio tutto ma in pratica non riesco ad avere risposte. Grazie

Il campo data è spesso Nothing, se fai l’interrogazione subito dopo aver inviato il DE815, se interroghi dopo è strano invece. Puoi postare qui un XML ricevuto?

In realtà non ricevo un XML, faccio fare alla classe proxy generata da .NET dopo l’invocazione del metodo ProcessAsync. A questo punto in e trovo codice, il messaggio, e il campo data che però è sempre nothing. ???

Module ServiziWs

Dim WithEvents wsSvc As svcRefWebSvc.MovimentazioniDASClient

Sub CreaServizio(ByRef cert As X509Certificate2, Optional flgFtp As Boolean = False)
    Dim wsBinding As New BasicHttpBinding()
    wsBinding.MessageEncoding = WSMessageEncoding.Mtom

      Const _tls12 As SslProtocols = SslProtocols.Tls12
      Const Tls12 As SecurityProtocolType = CType(_tls12, SecurityProtocolType)
      ServicePointManager.SecurityProtocol = Tls12
      ServicePointManager.ServerCertificateValidationCallback = AddressOf svrCertValidate

      wsBinding.Security.Mode = BasicHttpSecurityMode.Transport
      Dim wssAdress As EndpointAddress
      If MODOREALE Then
            wssAdress = New EndpointAddress("https://interop.adm.gov.it/MovimentazioniDASWeb/services/MovimentazioniDAS")
      Else
            wssAdress = New EndpointAddress("https://interoptest.adm.gov.it/MovimentazioniDASWeb/services/MovimentazioniDAS")
      End If

      wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate
      wsBinding.Security.Message.ClientCredentialType = System.ServiceModel.BasicHttpMessageCredentialType.Certificate

      wsSvc = New svcRefWebSvc.MovimentazioniDASClient(wsBinding, wssAdress)
      wsSvc.ClientCredentials.ClientCertificate.Certificate = cert
End Sub

Private Sub InviaFile

    TXTFILEINPUT = My.Computer.FileSystem.ReadAllText(nomeFileInput)
    Dim unicodeArray As Byte() = UnicodeGetStringToBytes(TXTFILEINPUT)
    Dim pos As Integer = nomeFileInput.LastIndexOf("\")
    Dim nomeBreveInput As String = nomeFileInput.Substring(pos + 1)
    DASINTERNO = -1
    If nomeBreveInput.Length > 9 AndAlso IsNumeric(nomeBreveInput.Substring(6, 4)) Then
        DASINTERNO = nomeBreveInput.Substring(6, 4)
    End If
    Dim rqs As New svcRefWebSvc.Richiesta()
    Dim sid As New svcRefWebSvc.RichiestaServiceId
    If nomeBreveInput.StartsWith("Rich801_") Then
        rqs.serviceId = sid.richiediDE801
    Else
        rqs.serviceId = sid.invioDE815
    End If
    Dim sdata As New svcRefWebSvc.RichiestaData
    sdata.dichiarante = "nnnnnnnnnnn"
    sdata.xml = unicodeArray
    Dim arData As RichiestaData()
    ReDim arData(0)
    arData(0) = sdata
    rqs.data = arData
    Dim rd = rqs.data
    wsSvc.processAsync(rqs)
End Sub

Private Sub wsSvc_processCompleted(sender As Object, e As processCompletedEventArgs) Handles wsSvc.processCompleted
    Try
        If e.Result IsNot Nothing Then
            Dim re = e.Result
            Dim ri As String = e.Result.IUT
            If e.Result.data Is Nothing Then
                If e.Result.esito.messaggio Is Nothing Then
                    MsgBox(e.Result.esito.codice & "- ERRORE! - IUT " & ri)
                Else
                    MsgBox(e.Result.esito.codice & "-" & e.Result.esito.messaggio(0).ToString, , "IUT " & ri)
                    If e.Result.esito.messaggio.Length <> 0 AndAlso DASINTERNO > 0 Then
                        AggiurnaIUT(e.Result.esito.codice & "-" & e.Result.esito.messaggio(0).ToString, ri)
                    End If
                End If

            Else
                Dim rd = System.Text.Encoding.UTF8.GetString(e.Result.data)
                MsgBox(rd, ri.ToString & "-" & re.ToString)
            End If
        Else
            MsgBox("Risposta vuota")
        End If
    Catch ex As Exception
        Dim err As String = ex.ToString
        If ex.InnerException IsNot Nothing Then err += vbCrLf + ex.InnerException.Message
        Dim er = MsgBox(err)

    End Try
End Sub

End Module

1 Mi Piace

Allora, attenzione. In fase di invio dell’XML, la WS delle Dogane restituisce un risultato di tipo “Risposta”, che contiene IUT, Codice Esito, Messaggio Esito, Data. Se osservi il PDF tecnico delle Dogane (7. CODICI STATO PER IL SERVIZIO DI RECUPERA STATO O ESITO), quelli sono i codici di risposta che il servizio può restituire. Ora, se l’invio non presenta errori sostanziali (firma non valida, certificato errato, ecc), dovrebbe restituire un codice “20. Acquisito a sistema”. Devi salvarti lo IUT ottenuto da questo invio e “darlo in pasto” ad una SECONDA WEB SERVICE, identificata nel paragrafo 6. SERVIZIO INTEROPSERVICE - RECUPERO DELL’ESITO del suddetto documento tecnico. Quindi, devi creare un nuovo client (io uso queste tre istruzioni su C#):
recuperoEsitoClient = new InteropNamespace.InteropService(); recuperoEsitoClient.ClientCertificates.Add(certificato); recuperoEsitoClient.Url = endpointRecuperoEsito;,
dove certificato è lo stesso utilizzato in fase di invio, ed endpointRecuperoEsito è quello del PDF(ovviamente cambia in base ad ambiente reale ed ambiente di prova).
La risposta di questa seconda WS è sempre di tipo “Risposta”, solo che stavolta il campo “Data” dovrebbe essere pieno, ed essere di tipo “Esito”. Io poi opero una serializzazione XML su tale formato per poter accedere ai vari campi dell’oggetto stesso, e quindi nella “sezione” Documento ci dovrebbe essere il PDF.

Attenzione 2: Fare un recupero esito subito dopo l’invio potrebbe dare un errore, dovuto al fatto che la WS non ha ancora elaborato il risultato. In questo caso è sufficiente riprovare dopo qualche secondo (puoi gestire con una temporizzazione o con un messaggio apposito). Inoltre, un messaggio comune è il “189”. In questo caso restituisce il CRS, ma non il PDF. Ancora, riprovare dopo qualche secondo dovrebbe dare il fatidico “200”, cioè tutto ok con PDF incluso.

P.S. Il recupero esito potrebbe restituire uno qualsiasi degli errori indicati nel PDF delle Dogane, che indica gli errori sul documento stesso (PIVA non valida, codice accisa sbagliato, ecc ecc)

1 Mi Piace

E’ possibile che tu stia saltando un passaggio?
Dal codice che hai incollato, vedo solo la chiamata “processasync” all’endpoint:

https://interop.adm.gov.it/MovimentazioniDASWeb/services/MovimentazioniDAS”;

utilizzando la callback sbagliata, quella che invece apartiene a “recuperaesito”, è cosi?

In realtà devi creare una nuova callback per la chiamata già detta, dalla quale, se la chiamata va a buon fine, ottieni l’IUT, intanto il sistema elabora la richiesta di emissione dell’e-das.

devi poi fare una chiamata a “recuperaEsitoAsync” dell’endpoint,
https://interop.adm.gov.it/InteropServiceWEB/services/InteropService

impostando l’IUT come parametro di richiesta, dal quale otterrai l’esito, ed eventualmente l’e-DAS

Grazie.
La tua diagnosì è corretta. Purtroppo però pur avendo modificato la call senza più inviare la richiesta DE801, ma solo la RichiestaEsito sull’endpoint interopservice, la chiamata a RecuperaEsitoAsync restituisce comunque una risposta Nothing

Sub CreaServizio(ByRef cert As X509Certificate2, Optional flgFtp As Boolean = False, Optional reqRpy As String = Nothing)
    Dim wsBinding As New BasicHttpBinding()
    wsBinding.MessageEncoding = WSMessageEncoding.Mtom

    'If Not flgFtp Then
    Const _tls12 As SslProtocols = SslProtocols.Tls12
    Const Tls12 As SecurityProtocolType = CType(_tls12, SecurityProtocolType)
    ServicePointManager.SecurityProtocol = Tls12
    ServicePointManager.ServerCertificateValidationCallback = AddressOf svrCertValidate

    wsBinding.Security.Mode = BasicHttpSecurityMode.Transport
    Dim wssAdress As EndpointAddress
    If MODOREALE Then
        If reqRpy Is Nothing Then
            wssAdress = New EndpointAddress("https://interop.adm.gov.it/MovimentazioniDASWeb/services/MovimentazioniDAS")
        Else
            wssAdress = New EndpointAddress("https://interop.adm.gov.it/InteropServiceWEB/services/InteropService")
        End If
    Else
        If reqRpy Is Nothing Then
            wssAdress = New EndpointAddress("https://interoptest.adm.gov.it/MovimentazioniDASWeb/services/MovimentazioniDAS")
        Else
            wssAdress = New EndpointAddress("https://interoptest.adm.gov.it/InteropServiceWEB/services/InteropService")
        End If
    End If

    wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate
    wsBinding.Security.Message.ClientCredentialType = System.ServiceModel.BasicHttpMessageCredentialType.Certificate
    Try
        If reqRpy Is Nothing Then
            wsSvc = New svcRefWebSvc.MovimentazioniDASClient(wsBinding, wssAdress)
            wsSvc.ClientCredentials.ClientCertificate.Certificate = cert
        Else
            svcRqs = New svcRqsEsito.InteropServiceClient(wsBinding, wssAdress)
            svcRqs.ClientCredentials.ClientCertificate.Certificate = cert
            svcRqs.recuperaEsitoAsync(reqRpy)
        End If
    Catch ex As Exception
        Dim er = ex.Message
        If ex.InnerException IsNot Nothing Then
            Dim ie = ex.InnerException.Message
        End If
    End Try
End Sub


Private Sub svcRqs_recuperaEsitoCompleted(sender As Object, e As svcRqsEsito.recuperaEsitoCompletedEventArgs) Handles svcRqs.recuperaEsitoCompleted
    Dim rpy = e.Result ' purtroppo sempre Nothing
End Sub

Prova ad utilizzare le istruzioni indicate nel mio post. Anche io ho avuto problemi utlizzando il binding, invece cosi funziona.

Grazie Giuseppe. In realtà non chiedevo “RecuperaEsito”, ma anche ora (che lo chiedo come da tue indicazioni) la risposte è comunque Nothing. Io sono scemo, ma Sogei mi sta facendo diventare ancora più scemo!

Grazie. Purtroppo ho ancora problemi ad usare il pdf. trovo la risposta, la converto da UTF8, prendo il Child “Documento” e lo converto da Base64, ottenendo un file in cui si vedono gli header tipici pdf, ma poi il tentativo di stampa NON funziona. Ovvio sbaglio ancora, ma cosa?

====================================================================

Private Sub svcRqs_recuperaEsitoCompleted(sender As Object, e As svcRqsEsito.recuperaEsitoCompletedEventArgs) Handles svcRqs.recuperaEsitoCompleted
    Try
        Dim iut As String = e.Result.IUT
        Dim cmdTxt As String
        If MODOREALE Then
            cmdTxt = "SELECT * FROM RIGHE "
        Else
            cmdTxt = "SELECT * FROM RIGHETEST "
        End If
        cmdTxt += "WHERE IUT='" & iut & "'"
        Dim conIut As New OleDb.OleDbConnection(sConn)
        Dim cmdIut As New OleDb.OleDbCommand(cmdTxt, conIut)
        conIut.Open()
        Dim rdr As OleDbDataReader = cmdIut.ExecuteReader
        Dim filename As String
        If rdr.HasRows Then
            rdr.Read()
            Dim anno As String = rdr("ANNO")
            Dim das As String = rdr("NUMERO_DAS")
            Filename = anno + If(DITTASEL.PartIva.Contains("01234567890"), "FA", "FC") + das + ".pdf"
        End If
        Dim rpy As Byte() = e.Result.data
        Dim risultato As String = System.Text.Encoding.UTF8.GetString(rpy)
        Dim xmlEsito As New XmlDocument
        xmlEsito.LoadXml(risultato)
        Dim pos As Integer = risultato.IndexOf("<IdentifynumberSRC>")
        Dim src As String = risultato.Substring(pos + 19, 21)
        pos = PATHEXPORT.LastIndexOf("\DAFIRMARE")
        xmlEsito.Save(PATHEXPORT.Substring(0, pos) + "\DASPDF\" + filename.Replace("pdf", "xml"))
        Dim doc As XmlNode = xmlEsito.LastChild("Documento")
        If doc IsNot Nothing Then
            Dim pathPdf As String = PATHEXPORT.Substring(0, pos) + "\DASPDF\" + filename
            Dim pdfWtr As New StreamWriter(pathPdf)
            Dim pdf64 As String = doc.InnerXml
            Dim pdfData As Byte() = System.Convert.FromBase64String(pdf64)
            Dim pdf As String = System.Text.ASCIIEncoding.ASCII.GetString(pdfData)
            pdfWtr.Write(Pdf)
            pdfWtr.Flush()
            pdfWtr.Close()
        End If
        Dim msg = e.Result.esito.messaggio
    Catch ex As Exception
        Dim err As String = ex.ToString
        If ex.InnerException IsNot Nothing Then err += vbCrLf + ex.InnerException.Message
        Dim er = MsgBox(err)

    End Try
End Sub

Fino a risultato ci siamo.
Poi ho una funzione che deserializza una stringa XML (nel tuo caso sarà “risultato”) in un object, basandomi sul model “Common.Esito”.
Chiamo questa variabile “esitoRisposta”.
A questo punto, “esitoRisposta” è un object che ha la stessa struttura di “Common.esito”.
Per creare il PDF, uso la seguente istruzione:
System.IO.File.WriteAllBytes(“documento.pdf”, esitoRisposta.Documento);

Fantastico, Giuseppe. Mi hai aiutato davvero. Ti ringrazio molto. Così funziona e stampo. A buon rendere

Perfetto, sono contento di esserti stato d’aiuto :slight_smile: