CAdES (ETSI EN 319 122) is the signature format of the P7M and P7S files: a file of any type is signed with a CMS / PKCS#7 signature with signed attributes. This C# sample creates an attached signature (a .p7m file that contains the signed file) and a detached signature (a .p7s file with the signature only).
How to create a P7M or P7S file in C#
- Create a
CadesSignatureobject, setDigitalSignatureCertificateand callApplyDigitalSignature(file). SignatureStandard:CadesBes(the default),Cmsfor the older software, or the long-term levelsCadesC,CadesXL,CadesLTandCadesA.IsDetachedSignature = truecreates a .p7s file; the signed file is then needed to verify the signature.- Optionally, the signature is time-stamped with
TimeStamping.ServerUrl.
C# code
/// <summary>
/// Signs a file and saves the signed file as .p7m: the content of the signed file is included in the signature.
/// </summary>
static void SignFileAsP7m(string unsignedFile, string p7mFile)
{
CadesSignature cadesSignature = new CadesSignature(LibrarySerialNumber);
cadesSignature.DigitalSignatureCertificate = LoadSigningCertificate();
// The signature format. CadesBes (CAdES-BES, ETSI EN 319 122) is the default value. Cms creates a standard
// CMS / PKCS#7 signature, recognized by the older software. The other values (CadesC, CadesXL, CadesLT, CadesA)
// add long-term validation data (certificates, revocation information and time-stamps) to the signature;
// they need an internet connection and, for CadesXL and CadesA, a time-stamping server.
cadesSignature.SignatureStandard = CadesSignatureStandard.CadesBes;
// The hash algorithm of the signature (SHA-256 is the default).
cadesSignature.HashAlgorithm = SignLib.HashAlgorithm.SHA256;
// Optionally, the signature can be time-stamped (RFC 3161) by a Time Stamping Authority (TSA).
// cadesSignature.TimeStamping.ServerUrl = new Uri("https://ca.signfiles.com/TSAServer.aspx");
// The signed file is included in the signature (IsDetachedSignature is false by default).
File.WriteAllBytes(p7mFile, cadesSignature.ApplyDigitalSignature(unsignedFile));
Console.WriteLine("The CAdES signature (.p7m) was created." + Environment.NewLine);
}
/// <summary>
/// Signs a file and saves the signature as .p7s: the signed file is not included, it is needed to verify the signature.
/// </summary>
static void SignFileAsDetachedP7s(string unsignedFile, string p7sFile)
{
CadesSignature cadesSignature = new CadesSignature(LibrarySerialNumber);
cadesSignature.DigitalSignatureCertificate = LoadSigningCertificate();
// The signed file is not included in the signature.
cadesSignature.IsDetachedSignature = true;
File.WriteAllBytes(p7sFile, cadesSignature.ApplyDigitalSignature(unsignedFile));
Console.WriteLine("The detached CAdES signature (.p7s) was created." + Environment.NewLine);
}
The same project verifies the signatures and extracts the signed file: see Verify CAdES signatures. What a P7S or P7M file contains is explained in What is a P7S or P7M file.
Run the full sample. The complete Visual Studio project P7M P7S CAdES Digital Signature is included in the library download, in the folder NET Sample Projects (.NET 8, .NET 9, .NET 10 and .NET 11) and in NET Framework Sample Projects (.NET Framework 4.6.2), with the test files and a test certificate. Without a serial number the library runs in demo mode. Download the library and the samples · User manual
Frequently asked questions
Should I use P7M or P7S?
Both contain a CMS / CAdES signature. P7M usually contains the signed file (attached), P7S usually contains only the signature (detached). Use the extension and the format required by the system that receives the file.
Can a P7M file have several signatures?
Yes. Sign the .p7m file again: the new signature is added to it as a co-signature.