How to attach AND HIDE a file in a PDF using Latex?

How to attach AND HIDE a file in a PDF using Latex?

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?

답변1

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}

답변2

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.

관련 정보