Table of Contents

Class CmsSignatureBuilder

Namespace
SimpleSign.Core.Crypto
Assembly
SimpleSign.Core.dll

Builds a CMS/PKCS#7 SignedData compatible with PAdES (adbe.pkcs7.detached). Uses exclusively System.Security.Cryptography from .NET — zero external dependencies.

public sealed class CmsSignatureBuilder
Inheritance
CmsSignatureBuilder
Inherited Members

Methods

AddUnsignedAttributes(byte[], IReadOnlyList<CmsAttribute>)

Adds unsigned attributes to an existing CMS/PKCS#7 SignedData structure. Parses the original CMS, injects the attributes into SignerInfo unsignedAttrs [1], and returns the rewritten DER. Follows the same pattern used for timestamp embedding.

public static byte[] AddUnsignedAttributes(byte[] cmsBytes, IReadOnlyList<CmsAttribute> unsignedAttributes)

Parameters

cmsBytes byte[]

DER-encoded CMS/PKCS#7 SignedData.

unsignedAttributes IReadOnlyList<CmsAttribute>

Unsigned attributes to inject (e.g., CertValues, RevocationValues, ArchiveTimeStamp).

Returns

byte[]

Rewritten CMS bytes with unsigned attributes appended.

Build(ReadOnlySpan<byte>, X509Certificate2, HashAlgorithmName, DateTimeOffset?, IReadOnlyList<X509Certificate2>?, IReadOnlyList<CmsAttribute>?, bool, string?, ILogger?)

Signs the provided bytes and returns a DER-encoded CMS/SignedData. The certificate must contain a private key (A1/PFX or Windows Store with minidriver).

public static byte[] Build(ReadOnlySpan<byte> dataToSign, X509Certificate2 certificate, HashAlgorithmName hashAlgorithm, DateTimeOffset? signingTime = null, IReadOnlyList<X509Certificate2>? extraCertificates = null, IReadOnlyList<CmsAttribute>? extraAttributes = null, bool padesAttributes = true, string? signatureAlgorithmOid = null, ILogger? logger = null)

Parameters

dataToSign ReadOnlySpan<byte>

The document bytes to be signed (ByteRange 1 + ByteRange 2).

certificate X509Certificate2

Certificate with private key.

hashAlgorithm HashAlgorithmName

Hash algorithm (SHA256 or SHA512).

signingTime DateTimeOffset?

Signing date/time (UTC).

extraCertificates IReadOnlyList<X509Certificate2>

Intermediate certificates to compose the chain.

extraAttributes IReadOnlyList<CmsAttribute>

Optional CAdES signed attributes (e.g., commitment-type, signature-policy).

padesAttributes bool

When true (default), adds the id-aa-signingCertificateV2 (ESS CertV2) attribute required by PAdES B-B.

signatureAlgorithmOid string

Optional override for the signature algorithm OID. When not null, this OID is used instead of the one auto-detected from the certificate. Must be compatible with the certificate's public key type (validated at call time). Primary use case: forcing RSASSA-PSS on an rsaEncryption certificate.

logger ILogger

Optional logger for debug diagnostics.

Returns

byte[]

BuildAsync(ReadOnlyMemory<byte>, X509Certificate2, Func<byte[], Task<byte[]>>, string, HashAlgorithmName, DateTimeOffset?, IReadOnlyList<X509Certificate2>?, IReadOnlyList<CmsAttribute>?, bool, ILogger?)

Signs the provided bytes using an external signing delegate and returns a DER-encoded CMS/SignedData. Use this overload for A3 tokens, HSMs, cloud KMS, or any scenario where the private key is not directly accessible via X509Certificate2.

public static Task<byte[]> BuildAsync(ReadOnlyMemory<byte> dataToSign, X509Certificate2 certificate, Func<byte[], Task<byte[]>> externalSigner, string signatureAlgorithmOid, HashAlgorithmName hashAlgorithm, DateTimeOffset? signingTime = null, IReadOnlyList<X509Certificate2>? extraCertificates = null, IReadOnlyList<CmsAttribute>? extraAttributes = null, bool padesAttributes = true, ILogger? logger = null)

Parameters

dataToSign ReadOnlyMemory<byte>

The document bytes to be signed (ByteRange 1 + ByteRange 2).

certificate X509Certificate2

The signer's public certificate (private key NOT required).

externalSigner Func<byte[], Task<byte[]>>

A delegate that receives the DER-encoded signed attributes and returns the raw signature bytes. For RSA: PKCS#1 v1.5 signature. For ECDSA: DER SEQUENCE { r, s } (RFC 3279). For EdDSA: raw signature bytes.

signatureAlgorithmOid string

The OID of the signature algorithm (e.g., "1.2.840.113549.1.1.11" for RSA-SHA256). Must match the algorithm used by the external signer.

hashAlgorithm HashAlgorithmName

Hash algorithm (SHA256 or SHA512).

signingTime DateTimeOffset?

Signing date/time (UTC).

extraCertificates IReadOnlyList<X509Certificate2>

Intermediate certificates to compose the chain.

extraAttributes IReadOnlyList<CmsAttribute>

Optional CAdES signed attributes (e.g., commitment-type, signature-policy).

padesAttributes bool

When true (default), adds the id-aa-signingCertificateV2 (ESS CertV2) attribute required by PAdES B-B. Set to false to produce a plain PKCS#7/CMS signature without PAdES-specific attributes.

logger ILogger

Optional logger for debug diagnostics.

Returns

Task<byte[]>

BuildSignedAttributes(byte[], string, DateTimeOffset, X509Certificate2, IReadOnlyList<CmsAttribute>?, bool)

Builds the DER-encoded signed attributes SET for a CMS signature.

public static byte[] BuildSignedAttributes(byte[] contentHash, string digestOid, DateTimeOffset time, X509Certificate2 signerCertificate, IReadOnlyList<CmsAttribute>? extraAttributes = null, bool padesAttributes = true)

Parameters

contentHash byte[]

The hash of the content being signed.

digestOid string

The digest algorithm OID.

time DateTimeOffset

Signing timestamp.

signerCertificate X509Certificate2

The signer's certificate (for signingCertificateV2).

extraAttributes IReadOnlyList<CmsAttribute>

Optional extra CAdES signed attributes.

padesAttributes bool

When true, includes PAdES-specific attributes (signingCertificateV2).

Returns

byte[]

BuildSignedData(string, string, HashAlgorithmName, byte[], byte[], X509Certificate2, List<X509Certificate2>, int, ILogger?)

Assembles a complete CMS/PKCS#7 SignedData DER structure from pre-built components. Used by the deferred signing pipeline and the CAdES external signer flow.

public static byte[] BuildSignedData(string digestOid, string signatureOid, HashAlgorithmName hashAlgorithm, byte[] signedAttrs, byte[] signature, X509Certificate2 signerCert, List<X509Certificate2> allCerts, int extraAttributeCount = 0, ILogger? logger = null)

Parameters

digestOid string

The digest algorithm OID used for the content hash.

signatureOid string

The signature algorithm OID.

hashAlgorithm HashAlgorithmName

The hash algorithm (used for RSASSA-PSS-params).

signedAttrs byte[]

Pre-built DER-encoded signed attributes SET.

signature byte[]

The raw signature bytes over the signed attributes.

signerCert X509Certificate2

The signer's certificate.

allCerts List<X509Certificate2>

All certificates to embed (signer + intermediates).

extraAttributeCount int

Count of extra signed attributes (for logging).

logger ILogger

Optional logger.

Returns

byte[]

ComputeHash(ReadOnlySpan<byte>, HashAlgorithmName)

Computes a cryptographic hash of the provided data using the specified algorithm.

public static byte[] ComputeHash(ReadOnlySpan<byte> data, HashAlgorithmName algorithm)

Parameters

data ReadOnlySpan<byte>
algorithm HashAlgorithmName

Returns

byte[]

DetectRsaPadding(X509Certificate2)

Detects the RSA padding mode from the certificate's signature algorithm. Returns PSS if the cert was issued with RSA-PSS, PKCS1 otherwise.

public static RSASignaturePadding DetectRsaPadding(X509Certificate2 cert)

Parameters

cert X509Certificate2

Returns

RSASignaturePadding

GetDigestOid(HashAlgorithmName)

Maps a HashAlgorithmName to its corresponding OID string.

public static string GetDigestOid(HashAlgorithmName alg)

Parameters

alg HashAlgorithmName

Returns

string

SignatureAlgorithmUsesNullParameter(string)

Returns true when the signature algorithm OID expects an explicit NULL parameter in the AlgorithmIdentifier.

public static bool SignatureAlgorithmUsesNullParameter(string signatureOid)

Parameters

signatureOid string

Returns

bool

ValidateSignatureAlgorithmCompatibility(X509Certificate2, string)

Validates that the requested signature algorithm OID is compatible with the certificate's public key type. Throws ArgumentException if not.

public static void ValidateSignatureAlgorithmCompatibility(X509Certificate2 cert, string signatureAlgorithmOid)

Parameters

cert X509Certificate2

The signer's certificate.

signatureAlgorithmOid string

OID of the signature algorithm to validate.

Exceptions

ArgumentException

The OID is incompatible with the certificate's key type.