---
title: "CAdES signatures"
description: "CAdES signatures in PKI SDK with the CadesSigner class, which creates and assembles the CMS signature package of any binary file, with a basic example."
canonical: "https://docs.lacunasoftware.com/en-us/articles/pki-sdk/signatures/cades"
locale: "en"
product: "PKI SDK"
last_updated: "2026-10-12"
---

# CAdES signatures

The CAdES standard lets you sign any binary file. The @Lacuna.Pki.Cades.CadesSigner class creates, customizes and
assembles the CMS signature package.

## Basic signature example

The code below shows a basic CAdES signature, to introduce and exercise the concepts and properties of this signer.

```cs
// Instantiate the signer object, which creates the signature
var signer = new CadesSigner();

signer.SetSigningCertificate(signingCert);       // the signer's certificate, with its private key
signer.SetDataToSign(toSign);                    // bytes or stream of the document to sign
signer.SetPolicy(CadesPolicySpec.GetCadesBes()); // CAdES-BES signature policy, with the Windows roots as TrustArbitrator
signer.ComputeSignature();                       // creates the attributes and gets the signer's signature

var cadesSig = signer.GetSignature();            // assembles the signature package and returns its BER-encoded bytes
```

## Advanced signature example

Below is a CAdES signature with the ICP-Brasil AD-RT signature policy (with a timestamp), followed by a description of each
Set method used on the signer.

```cs
PKCertificateWithKey signingCert = ...
byte[] toSign = ...

// ICP-Brasil AD-RT signature policy
var policy = BrazilCadesPolicySpec.GetAdrTempoV21();

// Timestamp requester for the timestamp authority at tsUri
var tsRequester = new TimestampRequester(tsUri);

// Instantiate the signer object, which creates the signature
var signer = new CadesSigner();

signer.SetSigningCertificate(signingCert);  // the signer's certificate, with its private key
signer.SetDataToSign(toSign);               // bytes or stream of the data to sign
signer.SetPolicy(policy);                   // signature policy
signer.SetTimestampRequester(tsRequester);  // timestamp requester
signer.ComputeSignature();                  // creates the attributes and gets the signer's signature

var cadesSig = signer.GetSignature();       // assembles the signature package and returns its BER-encoded bytes
```

* @Lacuna.Pki.Cades.CadesSigner.SetSigningCertificate(Lacuna.Pki.PKCertificateWithKey) -
  Sets the signer's certificate. The example uses a certificate with its private key. For how to load a certificate with
  its private key, see [Certificates with private key](https://docs.lacunasoftware.com/en-us/articles/pki-sdk/certificates/certs-with-key).

* @Lacuna.Pki.Cades.CadesSigner.SetDataToSign(System.Byte[]) -
  Sets the data to sign. The CAdES standard lets you sign any kind of binary file or data.

* @Lacuna.Pki.Cades.CadesSigner.SetPolicy(Lacuna.Pki.Cades.CadesPolicySpec) -
  Sets the signature policy. The SDK has policies already configured for the standards of some PKIs, such as ICP-Brasil,
  and also lets you create or customize your own policy. The example passes a policy already configured for the
  ICP-Brasil AD-RT standard. For more information on signature policies, see [Signature policies](https://docs.lacunasoftware.com/en-us/articles/pki-sdk/signatures/policies).

* @Lacuna.Pki.Cades.CadesSigner.SetTimestampRequester(Lacuna.Pki.ITimestampRequester) -
  Sets a requester that gets timestamps from a timestamp authority. The signature policy in the example (ICP-Brasil AD-RT)
  requires a timestamp, so the signer needs a timestamp requester.

## Remote signature

The @Lacuna.Pki.Cades.CadesSigner signer can also create a CAdES signature whose signing happens remotely, for instance
in the user's browser. In that case, the signer is set with a certificate without a private key:
@Lacuna.Pki.Cades.CadesSigner.SetSigningCertificate(Lacuna.Pki.PKCertificate). You also use the method that generates the
data the client signs (`Lacuna.Pki.Cades.CadesSigner.GenerateToSignBytes(Lacuna.Pki.SignatureAlgorithm@)`) and the method
that puts the signed data into the CAdES signature (`Lacuna.Pki.Cades.CadesSigner.SetPrecomputedSignature(System.Byte[])`).

For more information on remote signatures, see
[Signing with a remote key (signature in the browser)](https://docs.lacunasoftware.com/en-us/articles/pki-sdk/signatures/web-remote).

## Signature validation

With PKI SDK you can validate the whole signature package against a single policy:

```cs
CadesSignature signature = ...

Dictionary<CadesSignerInfo,ValidationResults> validationResults = signature.ValidateAllSignatures(CadesPoliciesForValidation.GetCadesBasic());

foreach (var item in validationResults) {
	Console.WriteLine("Passed checks:");
	item.Value.PassedChecks.ForEach(vi => Console.WriteLine(vi.Detail)); // prints every check that passed

	if (item.Value.HasErrors) { // if there are errors
		Console.WriteLine("Errors:");
		item.Value.Errors.ForEach(e => Console.WriteLine(e.Message)); // prints why the checks failed
	}
}
```
Or validate each signature against the policy you want:

```cs

var cadesSig = ...
var myIssuer = ...

CadesSignature signature = CadesSignature.Open(cadesSig);
foreach (var signerInfo in signature.Signers) {

	var policyMapper = signerInfo.SigningCertificate.Issuer.Equals(myIssuer)  // if the certificate was issued by my company's issuer, outside the Windows roots
		? CadesPoliciesForValidation.GetCadesBasic(new CustomArbitrator()) // use a custom trust arbitrator that trusts my issuer
		: CadesPoliciesForValidation.GetCadesBasic();			  // otherwise use the Windows roots as trusted roots

	ValidationResults result = signature.ValidateSignature(signerInfo, policyMapper); // validates the signature against the given policy

	Console.WriteLine("Passed checks:");
	result.PassedChecks.ForEach(vi => Console.WriteLine(vi.Detail)); // prints every check that passed
	if (result.HasErrors) {
		Console.WriteLine("Errors:");
		result.Errors.ForEach(e => Console.WriteLine($"{e.Message} - {e.Detail}")); // prints why the checks failed
	}
}

```

## See also

* @Lacuna.Pki.Cades.CadesSigner
* @Lacuna.Pki.PKCertificateWithKey
* @Lacuna.Pki.PKCertificate
* [Signature policies](https://docs.lacunasoftware.com/en-us/articles/pki-sdk/signatures/policies)
* [Signing with a remote key (signature in the browser)](https://docs.lacunasoftware.com/en-us/articles/pki-sdk/signatures/web-remote)

**Demos and samples**

- Live demo: [Sign a file with your certificate](https://try.lacunasoftware.com/en/pki-suite/sign-a-file)
- Live demo: [Validate a signed file](https://try.lacunasoftware.com/en/pki-suite/validate-a-signed-file)
- Sign a PDF with PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PadesSignatureSdkController.cs)
- Sign a file with CAdES using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/CadesSignatureSdkController.cs)
- Validate a signed PDF using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/OpenPadesSignatureSdkController.cs)
- Validate a CMS/CAdES signature using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/OpenCadesSignatureSdkController.cs)
- Validate a signed XML using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/OpenXmlSignatureSdkController.cs)
- Sign multiple files with CAdES using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/BatchCadesSignatureSdkController.cs)
- Sign a file with CAdES and a server key using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/CadesServerKeySdkController.cs)
- Merge CMS/CAdES signatures using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/MergeCadesSdkController.cs)
- Make a printer-friendly version of a CMS/CAdES signature using PKI SDK: [.NET](https://github.com/LacunaSoftware/PkiSuiteSamples/blob/master/dotnet/mvc/PkiSuiteAspNetMvcSample/Controllers/PrinterFriendlyCadesSdkController.cs)
