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
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
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)
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