Post-Quantum Cryptography (PQC) is often discussed in terms of algorithms. The practical deployment is not about algorithms alone; it is about how those algorithms are encoded into real-world cryptographic structures: X.509 certificates, CRLs, CMS signatures, OCSP responses, and timestamp tokens.
If those structures are not standards-aligned, interoperability fails.
NIST has officially released three finalised post-quantum cryptography standards (FIPS 203, 204, 205) designed to protect against future quantum computer attacks.
The approved algorithms include:
With another algorithm, FALCON, also slated for upcoming standardisation.
With ADSS Server 8.3.5 (released July 2024), Ascertia introduced production-grade PQC support across signing and PKI services. Release 8.4 focused on standards conformance and structural correctness especially for ML-DSA (CRYSTALS-Dilithium).
This article examines:
We also provide downloadable artefacts for the above so you can understand the structure better and also allow independent validation.
This is the first article in a four-part technical series covering structures, interoperability, performance, and HSM-backed PQC deployments.
ADSS Server aligns with the NIST PQC standardisation effort and supports finalised ML-DSA and ML-KEM parameter sets. ADSS Server ML-DSA implementations are according to published standards RFC 9881 (for certificates and CRLs) and RFC 9882 (for digital signatures based on CMS).
Supported parameter sets:
| ML-DSA | NIST Category | Symmetric Equivalent | RSA Equivalent |
|---|---|---|---|
| ML-DSA-44 | Level 2 | ~112 – 128 bits | ~RSA-2048 |
| ML-DSA-65 | Level 3 | ~192 bits | ~RSA-3072-7680* |
| ML-DSA-87 | Level 5 | ~256 bits | ~RSA-7680-15360* |
*RSA equivalence ranges because different standards round differently.
44 (Level 2), 65 (Level 3), 87 (Level 5) parameters provide NIST security strength levels equivalent to classical RSA-2048, RSA-3072 and RSA-7680 asymmetric crypto security categories.
Within ADSS Server, we have provided ML-DSA support for:
ML-DSA is used consistently across the PKI lifecycle, ensuring algorithm continuity.
ML-KEM (Module-Lattice-based Key Encapsulation Mechanism), formerly known as CRYSTALS-Kyber, is a NIST-standardised (FIPS 203) post-quantum algorithm designed to establish secure shared keys over insecure channels—protecting against future quantum computer attacks.
It is primarily used for key exchange in TLS, hybrid, and VPN protocols, offering fast performance and three security levels (512, 768, 1024).
Supported parameter sets:
| ML-KEM | NIST Category | Symmetric Equivalent | RSA Equivalent |
|---|---|---|---|
| ML-KEM-512 | Level 1 | ~128 bits | ~RSA-3072 |
| ML-KEM-768 | Level 3 | ~192 bits | ~RSA-7680 |
| ML-KEM-1024 | Level 5 | ~256 bits | ~15360 |
512 (Level 1), 768 (Level 3), and 1024 (Level 5) parameters are supported within ADSS Server for:
Together, these capabilities enable quantum-resistant key establishment within existing PKI hierarchies, allowing organisations to transition to post-quantum cryptography without disrupting established trust models.
The primary architectural objective of the industry standardisation effort was to ensure PQC support was added without altering the structural integrity of established PKI and signing standards, namely PQC had to fit into the following:
The only change is the cryptographic primitive, not the well-established trust model.
ML-DSA certificates generated by ADSS Server conform to RFC 9881, which defines integration of ML-DSA into PKIX.
The following certificate components are affected:
Here’s an example of a simplified ASN.1 structure:
Certificate ::= SIGNED{ TBSCertificate }
SIGNED{ToBeSigned} ::= SEQUENCE {
toBeSigned ToBeSigned,
algorithmIdentifier SEQUENCE {
algorithm SIGNATURE-ALGORITHM.
&id({SignatureAlgorithms}),
parameters SIGNATURE-ALGORITHM.
&Params({SignatureAlgorithms}
{@algorithmIdentifier.algorithm})
OPTIONAL
},
signature BIT STRING (CONTAINING SIGNATURE-ALGORITHM.&Value(
{SignatureAlgorithms}
{@algorithmIdentifier.algorithm}))
}
SubjectPublicKeyInfo (ML-DSA)
SubjectPublicKeyInfo {PUBLIC-KEY: IOSet} ::= SEQUENCE {
algorithm AlgorithmIdentifier {PUBLIC-KEY, {IOSet}},
subjectPublicKey BIT STRING
}
Key observations:
Compared to RSA-2048 or ECDSA-P256:
However:
Here is an example of ML-DSA-44 Certificate (ASN.1 Structure details):
Document Signing Certificate (ML-DSA-44) Certificate SEQUENCE (3 elem) └─ tbsCertificate TBSCertificate SEQUENCE (8 elem) ├─ version [0] (1 elem) │ └─ Version INTEGER 2 ├─ serialNumber CertificateSerialNumber INTEGER (125 bit) 38701396122719744824873050854229556033 ├─ signature AlgorithmIdentifier SEQUENCE (1 elem) │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 ← Signature algorithm OID for ML-DSA-44 ├─ issuer rdnSequence Name SEQUENCE (2 elem) ├─ validity Validity SEQUENCE (2 elem) │ ├─ notBefore utcTime Time UTCTime 2026-02-09 11:32:31 UTC │ └─ notAfter utcTime Time UTCTime 2027-02-09 11:32:31 UTC ├─ subject rdnSequence Name SEQUENCE (2 elem) ├─ subjectPublicKeyInfo SubjectPublicKeyInfo SEQUENCE (2 elem) │ ├─ algorithm AlgorithmIdentifier SEQUENCE (1 elem) ← PublicKey algorithm OID and value for ML-DSA-44 │ │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 │ └─ subjectPublicKey BIT STRING (10496 bit) 1111110111101010000110100111001011010110001000000110011111100011010101... └─ extensions [3] (1 elem) signatureAlgorithm AlgorithmIdentifier SEQUENCE (1 elem) ← Signature algorithm OID and value for ML-DSA-44 └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 signature BIT STRING (19360 bit) 0110011011001100010011101100000001100010011101100011001110101110110...
Here is the ML-DSA-44 Certificate object
The integration is structurally clean.
ADSS Server generates CRLs signed using ML-DSA compliant with RFC 9881.
Here’s the relevant structure:
CertificateList ::= SIGNED{ TBSCertList }
CertificateList ::= SEQUENCE {
tbsCertList TBSCertList,
signatureAlgorithm AlgorithmIdentifier,
signatureValue BIT STRING
}
The signatureAlgorithm field reflects the ML-DSA OID and the signature is encoded as a BIT STRING consistent with the selected parameter set.
Structural differences vs classical CRLs:
Again, the integration is structurally clean with no deviation from RFC 5280 CRL semantics.
Here is an example of CRL signed by ML-DSA-44 Certificate (CRL ASN.1 Structure details):
CRL (ML-DSA-44) CertificateList SEQUENCE (3 elem) └─ tbsCertList TBSCertList SEQUENCE (6 elem) ├─ version Version INTEGER 1 ├─ signature AlgorithmIdentifier SEQUENCE (1 elem) │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 ← Signature algorithm OID for ML-DSA-44 ├─ issuer rdnSequence Name SEQUENCE (2 elem) │ ├─ RelativeDistinguishedName SET (1 elem) │ │ └─ AttributeTypeAndValue SEQUENCE (2 elem) │ │ ├─ type AttributeType OBJECT IDENTIFIER 2.5.4.6 countryName (x.520 DN component) │ │ └─ value AttributeValue [?] PrintableString GB │ └─ RelativeDistinguishedName SET (1 elem) │ └─ AttributeTypeAndValue SEQUENCE (2 elem) │ ├─ type AttributeType OBJECT IDENTIFIER 2.5.4.3 commonName (x.520 DN component) │ └─ value AttributeValue [?] UTF8String ML-DSA-44_RootCA ├─ thisUpdate utcTime Time UTCTime 2026-02-09 11:06:01 UTC ├─ nextUpdate utcTime Time UTCTime 2026-02-10 11:06:01 UTC └─ crlExtensions [0] (1 elem) └─ Extensions SEQUENCE (2 elem) ├─ Extension SEQUENCE (2 elem) │ ├─ extnID OBJECT IDENTIFIER 2.5.29.35 authorityKeyIdentifier (x.509 extension) │ └─ extnValue OCTET STRING (24 byte) 30168014839536A58C470C0456A05B9225240CD8D54DC84D └─ Extension SEQUENCE (2 elem) ├─ extnID OBJECT IDENTIFIER 2.5.29.20 cRLNumber (x.509 extension) └─ extnValue OCTET STRING (3 byte) 020101 signatureAlgorithm AlgorithmIdentifier SEQUENCE (1 elem) └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 ← Signature algorithm OID and value for ML-DSA-44 signature BIT STRING (19360 bit) 0111110101010101101100010101010011001000100110000001101001110111100000...
Here is the CRL object signed by a CA using a ML-DSA-44 Certificate
ADSS Server generates CMS signatures using ML-DSA compliant with RFC 9882, which defines ML-DSA integration within CMS.
SignedData ::= SEQUENCE {
version CMSVersion,
digestAlgorithms SET OF DigestAlgorithmIdentifier,
encapContentInfo EncapsulatedContentInfo,
certificates [0] IMPLICIT CertificateSet OPTIONAL,
signerInfos SET OF SignerInfo
}
Within SignerInfo:
SignerInfo ::= SEQUENCE {
version CMSVersion,
sid SignerIdentifier,
digestAlgorithm DigestAlgorithmIdentifier,
signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
signatureAlgorithm AlgorithmIdentifier,
signature OCTET STRING,
unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL
}
Key points:
In ADSS Server we have applied this to:
Here is an example of CMS signature signed by ML-DSA-44 Certificate (CMS ASN.1 Structure details):
RFC 9882 compliant CMS Signature (ML-DSA-44) ContentInfo SEQUENCE (2 elem) ├─ contentType ContentType OBJECT IDENTIFIER 1.2.840.113549.1.7.2 signedData (PKCS #7) └─ content [0] (1 elem) └─ SignedData SEQUENCE (5 elem) ├─ version CMSVersion INTEGER 1 ├─ digestAlgorithms DigestAlgorithmIdentifiers SET (1 elem) │ └─ DigestAlgorithmIdentifier SEQUENCE (1 elem) ← Digest algorithm OID │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.3 sha-512 (NIST Algorithm) ├─ encapContentInfo EncapsulatedContentInfo SEQUENCE (2 elem) │ ├─ eContentType ContentType OBJECT IDENTIFIER 1.2.840.113549.1.7.1 data (PKCS #7) │ └─ eContent [0] (1 elem) │ └─ OCTET STRING (20978 byte) Demo File SigningDemo File SigningDemo File SigningDemo File Signin... ├─ CertificateSet [?] [0] (2 elem) │ ├─ certificate CertificateChoices SEQUENCE (3 elem) │ └─ certificate CertificateChoices SEQUENCE (3 elem) └─ signerInfos SignerInfos SET (1 elem) └─ SignerInfo SEQUENCE (6 elem) ├─ version CMSVersion INTEGER 1 ├─ sid issuerAndSerialNumber SignerIdentifier SEQUENCE (2 elem) ├─ digestAlgorithm DigestAlgorithmIdentifier SEQUENCE (1 elem) │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.3 sha-512 (NIST Algorithm) ├─ SignedAttributes [?] [0] (2 elem) │ ├─ Attribute SEQUENCE (2 elem) │ │ ├─ type AttributeType OBJECT IDENTIFIER 1.2.840.113549.1.9.3 contentType (PKCS #9) │ │ └─ values SET (1 elem) │ │ └─ AttributeValue [?] OBJECT IDENTIFIER 1.2.840.113549.1.7.1 data (PKCS #7) │ └─ Attribute SEQUENCE (2 elem) │ ├─ type AttributeType OBJECT IDENTIFIER 1.2.840.113549.1.9.4 messageDigest (PKCS #9) │ └─ values SET (1 elem) │ └─ AttributeValue [?] OCTET STRING (64 byte) 1F9C7C39FAF8B11580D06C803662725FB797425CCBC1CED4EC534332C3236876F31E54... ├─ signatureAlgorithm SignatureAlgorithmIdentifier SEQUENCE (1 elem) │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 ← Signature algorithm OID and value for ML-DSA-44 └─ signature SignatureValue OCTET STRING (2420 byte) 92D594F85A6B8253B27B5C7081CD39472302C0CAFD47E182A9C660442FDFED86F8E4 ...
Here is the CMS object signed by a ML-DSA-44 Certificate
ADSS Server produces ML-DSA-signed OCSP responses using the standard BasicOCSPResponse structure:
BasicOCSPResponse ::= SEQUENCE {
tbsResponseData ResponseData,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING,
certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
}
The signatureAlgorithm reflects ML-DSA OID usage.
The response remains fully compliant with PKIX OCSP semantics. Only the signature primitive changes.
Here is an example of OCSP Response signed by ML-DSA-44 Certificate (OCSP Response ASN.1 Structure details):
OCSP Response (ML-DSA-44) PKIMessage SEQUENCE (2 elem) ├─ header PKIHeader [?] ENUMERATED 0 └─ body ir PKIBody [0] (1 elem) └─ CertReqMessages SEQUENCE (2 elem) ├─ CertReqMsg [?] OBJECT IDENTIFIER 1.3.6.1.5.5.7.48.1.1 ocspBasic (OCSP) └─ CertReqMsg [?] OCTET STRING (10760 byte) 30822A043081CEA1283026310B30090603550406130247423117301506035504030... └─ certReq CertRequest SEQUENCE (4 elem) ├─ certReqId INTEGER [?] SEQUENCE (3 elem) ├─ certTemplate CertTemplate SEQUENCE (1 elem) │ └─ OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 ├─ BIT STRING (19360 bit) 101111010010101110100001001111111001001100100010010000000111100... └─ [0] (1 elem) └─ SEQUENCE (2 elem) ├─ SEQUENCE (3 elem) │ ├─ SEQUENCE (8 elem) │ └─ SEQUENCE (1 elem) │ └─ OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 │ └─ BIT STRING (19360 bit) 101010011110101010101101100000010110011010101101101101100001111000... └─ SEQUENCE (3 elem) ├─ SEQUENCE (8 elem) └─ SEQUENCE (1 elem) └─ OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 ← Signature algorithm OID and value for ML-DSA-44 └─ BIT STRING (19360 bit) 0101100000111010011010110101010100111000111010000001101101000001100010...
Here is the OCSP Response object signed by a ML-DSA-44 Certificate.
Timestamp tokens generated by ADSS Server are CMS SignedData structures containing TSTInfo.
ML-DSA is applied at the CMS signature layer, ensuring:
Here is an example of Timestamp Token signed by ML-DSA-44 Certificate (Timestamp Token ASN.1 Structure details):
Timestamp Token (ML-DSA-44) ContentInfo SEQUENCE (2 elem) ├─ contentType ContentType OBJECT IDENTIFIER 1.2.840.113549.1.7.2 signedData (PKCS #7) └─ content [0] (1 elem) └─ SignedData SEQUENCE (5 elem) ├─ version CMSVersion INTEGER 3 ├─ digestAlgorithms DigestAlgorithmIdentifiers SET (1 elem) │ └─ DigestAlgorithmIdentifier SEQUENCE (1 elem) ← Digest algorithm OID │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.3 sha-512 (NIST Algorithm) ├─ encapContentInfo EncapsulatedContentInfo SEQUENCE (2 elem) │ ├─ eContentType ContentType OBJECT IDENTIFIER 1.2.840.113549.1.9.16.1.4 tSTInfo (S/MIME Content Types) │ └─ eContent [0] (1 elem) ├─ CertificateSet [?] [0] (2 elem) │ ├─ certificate CertificateChoices SEQUENCE (3 elem) │ └─ certificate CertificateChoices SEQUENCE (3 elem) └─ signerInfos SignerInfos SET (1 elem) └─ SignerInfo SEQUENCE (6 elem) ├─ version CMSVersion INTEGER 1 ├─ sid issuerAndSerialNumber SignerIdentifier SEQUENCE (2 elem) ├─ digestAlgorithm DigestAlgorithmIdentifier SEQUENCE (1 elem) │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.3 sha-512 (NIST Algorithm) ├─ SignedAttributes [?] [0] (3 elem) │ ├─ Attribute SEQUENCE (2 elem) │ │ ├─ type AttributeType OBJECT IDENTIFIER 1.2.840.113549.1.9.3 contentType (PKCS #9) │ │ └─ values SET (1 elem) │ │ └─ AttributeValue [?] OBJECT IDENTIFIER 1.2.840.113549.1.9.16.1.4 tSTInfo (S/MIME Content Types) │ ├─ Attribute SEQUENCE (2 elem) │ │ ├─ type AttributeType OBJECT IDENTIFIER 1.2.840.113549.1.9.4 messageDigest (PKCS #9) │ │ └─ values SET (1 elem) │ │ └─ AttributeValue [?] OCTET STRING (64 byte) 46595C7481883E82E048F8F0F9F29C7EE6E6328330EBE512... │ └─ Attribute SEQUENCE (2 elem) ├─ signatureAlgorithm SignatureAlgorithmIdentifier SEQUENCE (1 elem) ← Signature algorithm OID and value for ML-DSA-44 │ └─ algorithm OBJECT IDENTIFIER 2.16.840.1.101.3.4.3.17 └─ signature SignatureValue OCTET STRING (2420 byte) FC3B9ADB9DDF9D7B95B694523BA70591F40546BB9215230EDA561F50C5882CC2B84D...
Here is the Timestamp Token object signed by a ML-DSA-44 Certificate.
The following artefacts are available for independent validation and ASN.1 inspection:
| Artefact | Algorithm | Format |
|---|---|---|
| ML-DSA Root (Self-Signed Issuing CA) | ML-DSA-2 | PEM / DER |
| Document Signing Certificate (End-Entity) | ML-DSA-2 | PEM / DER |
| Certificate Revocation List | ML-DSA-2 | PEM / DER |
| CMS Signature (Detached) | ML-DSA-2 | DER |
| OCSP Response | ML-DSA-2 | DER |
| Timestamp Token | ML-DSA-2 | DER |
| OCSP Response Signing Certificate | ML-DSA-2 | PEM / DER |
| Time Stamp Signing Certificate | ML-DSA-2 | PEM / DER |
These artefacts allow validation using independent toolchains such as OpenSSL and Bouncy Castle — which will be covered in detail in the next article.
From an architectural standpoint, the integration of PQC into ADSS Server demonstrates an important principle: Post-Quantum Cryptography does not require redesigning PKI — it requires correctly integrating new primitives into existing, well-defined structures.
While ML-DSA and ML-KEM introduce:
The trust model, validation logic, and structural semantics of PKIX and CMS remain intact. The migration challenge is therefore operational and performance-oriented — not structural.
The next article in this series will examine:
Cross-validation and interoperability testing with OpenSSL 3.6.1 and Bouncy Castle 1.83, including command-level walkthroughs and verification outputs.