We need to hide arbitrary data in a PDF in ways that do not affect rendering. We have to add data in a way to be difficult to identify and remove.
For researching:
- Metadata embedding
Use the XMP metadata block (in the /Metadata stream object).
It can contain arbitrary XML; you can base64 your string and store it in a custom namespace tag, e.g.:
<rdf:Description xmlns:wm="http://yourdomain/watermark">
<wm:HiddenID>BASE64ENCODED_DATA</wm:HiddenID>
</rdf:Description>
Con: Relatively easy to find if someone looks at metadata.
- Unreferenced object injection
PDFs can contain extra objects that are not referenced from any page, annotation, or catalog.
999 0 obj
<< /HiddenData (SomeBinaryOrBase64) >>
endobj
Readers ignore unreferenced objects, but they remain in the file.
Pro: Invisible in normal viewing, survives many editing operations.
Con: Can be removed by PDF optimizers that discard unreferenced objects.
- Inside page content streams as no-op operators
You can inject data in a page’s content stream in the form of comments or no-op commands:
%Hidden: BASE64_DATA
0 0 m
0 0 l
n
% starts a comment;
PDF interpreters ignore it during rendering.
Pro: Stays in visible page streams, so optimizers may leave it.
Con: Anyone dumping the stream sees it.
- In object stream padding
PDF object streams often have unused padding between tokens or within binary streams (when compression is off).
You can inject bytes inside these padding areas.
Pro: Very stealthy.
Con: Risky if any PDF editor recompresses streams — could lose data.
We need to hide arbitrary data in a PDF in ways that do not affect rendering. We have to add data in a way to be difficult to identify and remove.
For researching:
Use the XMP metadata block (in the /Metadata stream object).
It can contain arbitrary XML; you can base64 your string and store it in a custom namespace tag, e.g.:
Con: Relatively easy to find if someone looks at metadata.
PDFs can contain extra objects that are not referenced from any page, annotation, or catalog.
Readers ignore unreferenced objects, but they remain in the file.
Pro: Invisible in normal viewing, survives many editing operations.
Con: Can be removed by PDF optimizers that discard unreferenced objects.
You can inject data in a page’s content stream in the form of comments or no-op commands:
PDF interpreters ignore it during rendering.
Pro: Stays in visible page streams, so optimizers may leave it.
Con: Anyone dumping the stream sees it.
PDF object streams often have unused padding between tokens or within binary streams (when compression is off).
You can inject bytes inside these padding areas.
Pro: Very stealthy.
Con: Risky if any PDF editor recompresses streams — could lose data.