0

Embedding a file is fairly easy using LaTeX (see, for example: Embed link to an embedded file).

Hiding an embedded file is also possible and fairly easy to do outside LaTeX (see, for example: https://blog.didierstevens.com/2009/07/01/embedding-and-hiding-files-in-pdf-documents/)

But I'm almost certain that it is possible to do the same (i.e., embed a file AND hide it from the attachment list) using only Latex...

Motivation: to be able to include the tex source code as an attachment that is hidden from the attachment list.

Any grey beard out there knowing the answer to this one?

  • I cannot answer your question but I do know this: If the resulting PDF must meet PDF/X or PDF/A specs (common requirements here), then a hidden attachment is forbidden. This makes sense, when you consider the purpose of PDF/X and PDF/A documents. Also, even if you hide the source code from display by a PDF reader, the code can nevertheless be revealed by other software; so you cannot prevent someone from seeing it, unless your attachment is (say) an encrypted and password-protected zip archive. – user139954 Feb 20 '18 at 18:58
  • Hi RobtAll! Thanks for your swift reply. That's quite ok... My intention is to include the tex source code of my CV on the pdf. No need for me to meet /X or /A specs :) Also, as you mention the tex file could be encrypted with gpg, for example. Cheers – user851539 Feb 20 '18 at 19:01
7

The "hidden" embedded file in the blog post is not an embedded file in the sense of the PDF standard, so the question is what you really want:

If you only want to include the content from the file in the generated PDF, you can add a PDF stream: If you write \immediate\pdfobj file{some-filename.tex}, the file some-filename.tex is copied into the PDF as a stream. If you want to see this without writing a PDF parser, you can use

\documentclass{article}
\pdfobjcompresslevel=0% Don't hide the objects
...
\begin{document}
...
% Disable compression for this one object
{\pdfcompresslevel=0\immediate\pdfobj file{some-filename.tex}}
...
\end{document}

If you open the resulting PDF file in an editor, somewhere you will something like: (The first number may vary)

11 0 obj
<Here comes the content of some-filename.tex>
endobj

This object will not be visible in any PDF viewer.

Of course, this isn't really embedded. A second attempt: Embed the file, but do not list it in /EmbeddedFiles. You can use

\documentclass{article}
\usepackage{embedfile}
\pdfobjcompresslevel=0% Don't hide the objects
...
\begin{document}
...
{\pdfcompresslevel=0\embedfile{some-filename.tex}}
\makeatletter
\global\let\EmFi@list\empty
\makeatother
...
\end{document}

I partially disabled compression again so that you can find the file in the resulting PDF. The \global\let\EmFi@list\empty makes the embedfile package forget about all the files up to this point, so they will never be written into the list of embedded files, but the /EmbeddedFile PDF object with the file content and some metadata is still written. You can't easily make this visible, because the catalog entries are missing.

If you try to reproduce the blog post you referenced and change the case of /EmbeddedFiles, you have to replace the output routine of embedfile:

\documentclass{article}
\usepackage{embedfile}
\pdfobjcompresslevel=0% Don't hide the objects, otherwise you can't see
                      % /Embeddedfiles, so you also can't change it back
\makeatletter
% The following is mostly copied from embedfile.sty, (C) by Heiko Oberdiek
% But all the errors are propably introduced by me
\def\embedfilefinish{%
  \ifEmFi@finished
    \EmFi@Error{%
      Too many invocations of \string\embedfilefinish
    }{%
      The list of embedded files is already written.%
    }%
  \else
    \ifx\EmFi@list\empty
    \else
      \global\EmFi@finishedtrue
      \begingroup
        \def\do##1##2{%
          (##1)##2%
        }%
        \immediate\pdfobj{%
          <<%
            /Names[\EmFi@list]%
          >>%
        }%
        \pdfnames{%
          % Changed name to make this invalid
          /Embeddedfiles \the\pdflastobj\space 0 R%
        }%
      \endgroup
    \fi
  \fi
}
\makeatother
\begin{document}
...
\embedfile{hidden.tex}
...
\end{document}
  • 1
    Perfect Zauguin! I'm selecting this as the correct answer. You can even use pdftosrc in linux to extract the "hidden code" on the pdf stream afterwards. Quick comment: perhaps the best way to add the source tex file to the stream is: \immediate\pdfobj stream attr {/Type /SourceFile /SourceName (source_file.tex)} file{source_file.tex} \pdfcatalog{/SourceObject \the\pdflastobj\space 0 R} Cheers – user851539 Feb 20 '18 at 22:19
1

If you are of a mind to do this in a roundabout way: Use the GIMP graphics program and ImageMagick. You will also need to be able to extract images from a PDF: On Linux, try the pdfimages command-line tool. Or try the pdfimages.exe command line tool, from Xpdf.

  1. In GIMP, create a new image of size 100x100 pixels. This will have more bytes than the plain text of your CV. If not, use a larger image.

  2. Fill the image with white. Export it as *.bmp (Windows bitmap) even if you are not on Windows. Do not use any encoding, and do not save color information or anything else.

  3. Open the plain text of your CV. Place some spaces before it begins, and after it ends. Copy everything to the clipboard.

  4. Open the *.bmp image in a hex editor. After its prologue, you will see numerous FF bytes, meaning white. Somewhere in there, over-write a bunch of FF with your pasted text. Save.

  5. You should be able to open the edited *,bmp in GIMP, where the text will appear as random-looking dark lines. Export it as PNG, using 0 compression and without saving any information (no Exif, etc.).

  6. Using ImageMagick: mogrify -strip thatimage.png On Windows: magick mogrify -strip thatimage.png

  7. Using the includegraphics command (package graphicx), place the *.png image in an inconspicuous place in the CV TeX file. You may scale it down, to be even smaller. You may also use the textpos package to position a blank white rectangle (image) atop your *.png image, so that nothing shows in print. Or, if the CV contains your photo or a corporate logo, you can place the photo or logo atop the *.png.

  8. If you are not placing one image atop another, then it is possible to have the PDF meet PDF/X or PDF/A. As far as PDF is concerned, the edited png is just an image. It doesn't know about the text inside. If you are placing one image atop another, then it (usually) won't meet PDF/X or PDF/A, unless you are using a recent version of those standards.

  9. The *.png image is stored using PDF methods, not "as png". Later, you can extract it using pdfpages command line (Linux), but be sure to specify the output as png format, not the default ppm format.

  10. In GIMP, open the extracted png, and convert to bmp, again ensuring that no encoding or stray data is written.

  11. Open the extracted bmp in a hex editor, and behold: Your text is there, lurking among the FF bytes.

The general name for concealing information in an image is "steganography". You can read about it online. This is not a good example, since the original data can be seen by anyone who knows what you did, without the need for decryption.

I just tested my own advice, and it works. However, if you wish to try it, you must carfully choose which options you use (and don't use) at each step, or the image's text will become garbled.

  • 1
    Thanks RobtAll! I was looking more for an automated process, though. I'm already using steganography on the signature image in my CV ;) There is this neat program in linux - steghide - that you can use to quickly encode and extract info from images. It's like a watermark I always use. Hidding in plain sight ;) BTW loved the Q&A on your novel package! – user851539 Feb 20 '18 at 21:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.