CAdES, P7M, P7S Digital Signature in C#

static void DigitallySignInCAdESFormat(string unsignedDocument, string signedDocument)
{
      CadesSignature cs = new CadesSignature("");

      //create a CAdES-BES signature
      cs.SignatureStandard = CadesSignatureStandard.CadesBes;
      //Hash algorithm
      cs.HashAlgorithm = SignLib.HashAlgorithm.SHA256;
      //optionally, the signature can be timestamped.
      cs.TimeStamping.ServerUrl = new Uri("https://ca.signfiles.com/TSAServer.aspx");

      //Load the signature certificate from a PFX or P12 file
      //cs.DigitalSignatureCertificate = DigitalCertificate.LoadCertificate("cert.pfx", "123456");

      //Load the certificate from Microsoft Store. 
      //The smart card or USB token certificates are usually available on Microsoft Certificate Store (start - run - certmgr.msc).
      //If the smart card certificate not appears on Microsoft Certificate Store it cannot be used by the library
      cs.DigitalSignatureCertificate = DigitalCertificate.LoadCertificate(false, string.Empty, "Select Certificate", "Select the certificate for digital signature");
      DigitalCertificate.SmartCardPin = "123456";

      //write the signed file
      //usually, the signed CAdES file should be saved with .p7s or .p7m extension
      File.WriteAllBytes(signedDocument, cs.ApplyDigitalSignature(unsignedDocument));
}

static void VerifyCAdESSignature(string signedDocument)
{
      CadesVerify cv = new CadesVerify(signedDocument, "");

      Console.WriteLine("Number of signatures: " + cv.Signatures.Count.ToString());

      //verify every digital signature from the signed document
      foreach (CadesSignatureInfo csi in cv.Signatures)
      {
        Console.WriteLine("Hash Algorithm: " + csi.HashAlgorithm.FriendlyName);
        Console.WriteLine("Signature Certificate Information");
        ExtractCertificateInformation(csi.SignatureCertificate);
        Console.WriteLine("Signature Is Valid: " + csi.SignatureIsValid.ToString());
        Console.WriteLine("Signature Time: " + csi.SignatureTime.ToLocalTime().ToString());
        Console.WriteLine("Is Timestamped: " + csi.SignatureIsTimestamped);

        if (csi.SignatureIsTimestamped == true)
        {
          Console.WriteLine("Hash Algorithm: " + csi.TimestampInfo.HashAlgorithm.FriendlyName);
          Console.WriteLine("Is TimestampAltered: " + csi.TimestampInfo.IsTimestampAltered.ToString());
          Console.WriteLine("TimestampSerial Number: " + csi.TimestampInfo.SerialNumber);
          Console.WriteLine("TSA Certificate: " + csi.TimestampInfo.TsaCertificate.Subject);
        }
      }
}

static void ExtractCertificateInformation(X509Certificate2 cert)
{
      Console.WriteLine("Certificate subject:" + cert.Subject);
      Console.WriteLine("Certificate issued by:" + cert.GetNameInfo(X509NameType.SimpleName, true));
      Console.WriteLine("Certificate will expire on: " + cert.NotAfter.ToString());
      Console.WriteLine("Certificate is time valid: " + DigitalCertificate.VerifyDigitalCertificate(cert, VerificationType.LocalTime).ToString());
}

static void Main(string[] args)
{
      //usually, the signed CAdES file should be saved with .p7s or .p7m extension
      DigitallySignInCAdESFormat("test.txt", "test.txt.p7s");
      VerifyCAdESSignature("test.txt.p7s");
}

See also: