domenica 18 ottobre 2026

C# Windows Forms: estrarre un certificato digitale da un file P7M

In questo esempio vediamo come estrarre un certificato digitale da un file firmato digitalmente in formato .p7m, utilizzando il linguaggio C# e l'ambiente Windows Forms.

Un file P7M può contenere uno o più certificati. Vedremo quindi come recuperare i certificati presenti nella firma e come salvare un certificato in un file con estensione .cer.

1. Estrarre i certificati dal file P7M

Per prima cosa, creiamo una funzione che legge il file P7M e restituisce un oggetto X509Certificate2Collection, contenente i certificati inclusi nella struttura CMS.

C#

  public static X509Certificate2Collection EstraiCertificati(string percorso)

  {

      byte[] dati = File.ReadAllBytes(percorso);

 

      var signedCms = new SignedCms();

      signedCms.Decode(dati);    

 

       

      return signedCms.Certificates;

  }



La funzione legge il contenuto del file, lo decodifica mediante la classe SignedCms e restituisce la raccolta dei certificati presenti nella struttura della firma.

2. Recuperare il nome dal certificato
Per ricavare un nome da utilizzare nel nome del file, possiamo creare una funzione che recupera il nome semplice del certificato.

C#

 

private string RilevaNomeDalSubject(X509Certificate2 certificato)

 {

     return certificato.GetNameInfo(X509NameType.SimpleName, false);

 }


3. Selezionare e salvare il certificato estratto

Di seguito riportiamo il codice che consente di estrarre un certificato dal file P7M e di salvarlo sul computer in formato .cer.



C#

  private void BtnEstraiFileCertificato_Click(object sender, EventArgs e)

  {

      if (string.IsNullOrEmpty(TxtPercorsoNomeFileP7mPerCertificato.Text.Trim()))

      {

          Utility.MessaggioInfo("Selezionare un file firmato di tipo .p7m");

 

          return;

 

      }

 

           

 

      var certificati = EstraiCertificati(TxtPercorsoNomeFileP7mPerCertificato.Text.Trim());

 

      if (certificati.Count == 0)

      {

          MessageBox.Show("Nessun certificato trovato nel file.");

          return;

      }

 

      X509Certificate2 certificato = certificati[0];

            

      string valoreSubectNameCertificato = certificato?.SubjectName?.Name ?? "";

      if (valoreSubectNameCertificato =="")

      {

          valoreSubectNameCertificato = "Certificato";

      }

      using (SaveFileDialog saveFileDialog = new SaveFileDialog())

      {

          saveFileDialog.Filter = "Certificato DER (*.cer)|*.cer";

          saveFileDialog.Title = "Salva il certificato.";

 

          // Suggerisce un nome basato sul subject

          string NomeFile = RilevaNomeDalSubject(certificato);

          saveFileDialog.FileName = $"{NomeFile}.cer";

          saveFileDialog.DefaultExt = "cer";

          saveFileDialog.AddExtension = true;

 

          if (saveFileDialog.ShowDialog() == DialogResult.OK)

          {

              try

              {

                  string percorsoNomeFileDaSalvare = saveFileDialog.FileName;

                        

                  if (certificato != null)

                  {

                      byte[] certBytes = certificato.Export(X509ContentType.Cert);

                      File.WriteAllBytes(percorsoNomeFileDaSalvare, certBytes);

 

                  }

                           

 

 

 

                  MessageBox.Show($"Certificato salvato con successo:\n{percorsoNomeFileDaSalvare}",

                      "Successo", MessageBoxButtons.OK, MessageBoxIcon.Information);

              }

              catch (Exception ex)

              {

                  MessageBox.Show($"Errore nel salvataggio: {ex.Message}",

                      "Errore", MessageBoxButtons.OK, MessageBoxIcon.Error);

              }

          }

      }

 

 

  }



Nota: l'estrazione di un certificato da un file P7M non implica che la firma digitale sia valida o che il certificato sia attendibile. Il metodo EstraiCertificati restituisce i certificati inclusi nella struttura CMS, che non necessariamente comprendono l'intera catena di certificazione. Inoltre, il file .cer generato contiene il certificato pubblico, senza la relativa chiave privata.

Nessun commento: