title: Creating an AES 256 encrypted PDF on OS X
body: <p>The standard Cocoa PDF API (PDFDocument and CGPDFContext) can create encrypted PDF documents via <code>writeToFile:withOptions:</code>.  However, according to the documentation, it only supports the encryption methods for very old PDF file formats.</p>
  
  <p>The only public API for changing encryption options is <code>kCGPDFContextEncryptionKeyLength</code> but it does not support anything larger than 128 bits (and I'm pretty sure that's the old algorithm to boot).  I thought that maybe the documentation was just stale, and maybe I could get it to use the new AES 256 algorithm by telling it to use a 256 bit key length.</p>
  
  <p>No joy; but at least the documentation is accurate.  Maybe there is some way to get the actual PDF dictionary?  The PDF spec shows what values need to be set for the new encryption, but I don't see a way to modify the raw underlying dictionary either, via the cocoa API.</p>
  
  <p>I'm somewhat surprised, with Apple's tight PDF integration, that this is not obvious in the API.  Surely, there must be folks generating (more) secure PDF files by utilizing the newer AES 256 option.</p>
  
  <p>Obviously, I can just encrypt it myself, but then normal PDF readers will be unable to open the document.</p>
  
  <p>I'd appreciate any assistance in figuring out how to accomplish this task.</p>
  
  <hr>
  
  <p><strong>EDIT</strong></p>
  
  <p><strong>On Assumptions</strong></p>
  
  <p>I am certainly assuming that the current PDF documents generated using the Cocoa PDF API are not AES, and are using old PDF encryption techniques.  However, I don't think those assumptions are too wild.  They are based on the following.</p>
  
  <ul>
  <li><p>Apple's documentation for <code>kCGPDFContextEncryptionKeyLength</code> says this...</p>
  
  <blockquote>
    <p>The encryption key length in bits; see Table 3.18 "Entries common to
    all encryption dictionaries", PDF Reference: Adobe PDF version 1.5
    (4th ed.) for more information. Optional; if present, the value of
    this key must be a CFNumber object with value which is a multiple of 8
    between 40 and 128, inclusive. If this key is absent or invalid, the
    encryption key length defaults to 40 bits.</p>
  </blockquote>
  
  <p>Since it references 1.5,  I assume either the documentation is old and outdated, or they don't support anything more recent than PDF 1.5.  In the original post I noted that I already tried a large value for key length, and the code would not let me set it larger than 128.</p></li>
  <li><p>The PDF specification provided the following encryption (according to <a href="http://en.wikipedia.org/wiki/Portable_Document_Format" rel="nofollow">http://en.wikipedia.org/wiki/Portable_Document_Format</a>, verified with a few other sources)</p>
  
  <p>1.1 - RC4 40 bits</p>
  
  <p>1.3 - PKCS#7, but not documented until 1.5</p>
  
  <p>1.4 - RC4 up to 128 bits</p>
  
  <p>1.5 - PKCS#7 with SHA-1, RSA up to 4096 bits</p>
  
  <p>1.6 - AES encryption; PKCS#7 with SHA256, DSA up to 4096-bits</p>
  
  <p>1.7 - 256-bit AES encryption</p></li>
  <li><p>I have created PDF files with key size settings at both 40 and 128.  With the 40-bits setting, the generated PDF file was PDF 1.3 format.  With the 128-bits setting, the generated PDF file was PDF 1.4 format.</p>
  
  <p>Since neither file is created with a format that supports AES, I assume the encryption is not AES, and is thus RC4.</p></li>
  </ul>
  
  <p>I would love to be wrong, or I would just equally love to be shown how to create a more modern PDF file format using the Cocoa API, and with the more modern encryption algorithms.</p>
  
  <p><strong>On Passwords</strong></p>
  
  <p>@Zaph makes a great point about passwords.  However, these PDF documents are being generated automatically.  The key is generated automatically, using /dev/random as a source for randomness.  Thus, while the password will not be awesome, it will avoid most of the weakness of human-generated passwords.  The later versions of the PDF specification allow 127-byte unicode passwords as well.</p>
  
  <p>The generated passwords will then be shared with intended recipients using private/public key encryption.</p>
  
  <p>I don't have to protect Fort Knox, but I have to at least adhere to reasonable modern practices, and RC4 just does not qualify.</p>
  
  <p>Any other input would be extremely helpful.</p>