Fixing IRBM’s DS333 Error: Signature Digest Mismatch in UBL Invoice #ds333 #irbsigning

Most important: <ds:SignatureValue> must contain the digital signature (SHA256-RSA encrypted hash) of the raw, minified, canonicalized XML output of <Invoice> — before any hashing, not the full invoice or the Signature block itself.

What is DS333?

DS333 is an IRBM e-Invoice error that means the digest or signature of the <Invoice> block is incorrect. This is a cryptographic failure — the server re-calculates the hash of your minified Invoice block and compares it against what you signed. If they don’t match, you get:


"DS333: Signature digest mismatch"

Why does DS333 happen?

  • ❌ You signed SignedInfo before finalizing all child nodes (e.g. Reference, CanonicalizationMethod)
  • ❌ You hashed the wrong thing (e.g. Invoice, Signature, whole document)
  • ❌ You didn’t canonicalize <SignedInfo> using Exclusive C14N
  • ❌ You inserted placeholder or signed an XML with whitespace differences

Fix Strategy (Laravel + xmlseclibs)

Step 1: Canonicalize & Sign SignedInfo Block

After building <SignedInfo> including Reference + Digest, do this:


$signedInfoXml = $objDSig->sigNode->getElementsByTagName('SignedInfo')->item(0)->C14N(true, false);
$privateKey = openssl_pkey_get_private($this->pkeyPem, $this->pkeyPassphrase);
openssl_sign($signedInfoXml, $signatureBin, $privateKey, OPENSSL_ALGO_SHA256);
$signatureValue = base64_encode($signatureBin);

Step 2: Insert SignatureValue


$signatureValueNode = $doc->createElementNS($ds, 'ds:SignatureValue', $signatureValue);
$signatureNode->appendChild($signatureValueNode);

Step 3: Canonicalize using Exclusive C14N

Inside <SignedInfo> tag:


<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>

Do not use inclusive or default Canonicalization.

Correct Signing Order

  1. Create full UBL XML (with UBLExtensions and placeholder)
  2. Build <SignedInfo> with Reference and Digest
  3. Canonicalize SignedInfo
  4. Generate SignatureValue using SHA256 + private key
  5. Insert SignatureValue into Signature block
  6. Insert KeyInfo with X509Certificate
  7. Place entire <ds:Signature> inside <ext:UBLExtensions>

Validation Tip


$canonicalSignedInfo = $signedInfoNode->C14N(true, false);
$hashCheck = base64_encode(hash('sha256', $canonicalSignedInfo, true));
Log::debug('SignedInfo Digest', [$hashCheck]);

Common Mistakes to Avoid

  • ❌ Signing the whole invoice instead of Invoice
  • ❌ Inserting SignatureValue before completing Reference block
  • ❌ Using non-canonicalized XML with extra spaces or formatting
See also  Day 6: Digitally Sign UBL XML Using XMLSecLibs #xmlsignature #irbsigning

Summary

DS333 is fixed by properly signing <Invoice> using:

  • Exclusive C14N
  • SHA256 hash
  • RSA private key
  • Accurate and final XML block with all Reference data included

Never sign before building the exact final version of <Invoice>.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.