I wanted to build an awesome place for people to discuss module specific issues, but I don't have any more time for this, and there are much better places to discuss Perl-related issues. I'd recommend asking your question on Stack Overflow or on Perl Monks.
If you are looking for a Perl tutorial or Perl-related news, I hope these links will serve you well.
Posted on 2008-10-18 18:52:17-07 by joe312213
128 bit pdf encryption (and password bug)
Hi!

I'm trying to get your module to do version 2 (128bit) encryption.

I've read the relevant bits of the pdf spec and it seems all I should have done was add a 'Length' key to the dictionary (type number, value 128), set 'V' to 2 (also further down in the set_passwords sub, set
$self->{keylength} = 128
instead of 40) and bobs your uncle. unfortunately it didn't work out that way... my script runs and produces an encrypted pdf, but the keys are not accepted.

This is what I changed the set_passwords function in
CAM::PDF::Decrypt
to:
sub set_passwords { my $self = shift; my $doc = shift; my $opass = shift; my $upass = shift; my $p = shift || $self->{P} || $self->encode_permissions(1,1,1,1); require Digest::MD5; require Crypt::RC4; $doc->clean(); # Mark EVERYTHING changed # if no crypt block, create it and a trailer entry # changed V from 1 to 2 and added Length node my $cryptkeylength = 128; my $dict = CAM::PDF::Node->new('dictionary', { Filter => CAM::PDF::Node->new('label', 'Standard'), V => CAM::PDF::Node->new('number', 2), Length => CAM::PDF::Node->new('number', $cryptkeylength), R => CAM::PDF::Node->new('number', 2), P => CAM::PDF::Node->new('number', $p), O => CAM::PDF::Node->new('string', q{}), U => CAM::PDF::Node->new('string', q{}) }); my $objnode = CAM::PDF::Node->new('object', $dict); my $objnum = $self->{EncryptBlock}; if ($objnum) { $doc->replaceObject($objnum, undef, $objnode, 0); } else { $objnum = $doc->appendObject(undef, $objnode, 0); } if (!$doc->{trailer}) { die 'No trailer'; } # This may overwrite an existing ref, but that's no big deal, just a tiny bit inefficient $doc->{trailer}->{Encrypt} = CAM::PDF::Node->new('reference', $objnum); # if no ID, create it if (!$doc->{ID}) { $doc->createID(); #print 'new ID: ' . unpack('h*',$doc->{ID}) . ' (' . length($doc->{ID}) . ")\n"; } #else { print 'old ID: '.unpack('h*',$doc->{ID}) . ' (' . length($doc->{ID}) . ")\n"; } # Recompute O and U # To do so, we must set up a couple of dependent variables first: $self->{R} = 2; $self->{keylength} = $cryptkeylength; $self->{P} = $p; # set O (has to be first because U uses O) $self->{O} = $self->_compute_o($opass, $upass); # set U $self->{U} = $self->_compute_u($doc->{ID}, $upass); # save O and U in the Encrypt block $dict = $doc->getObjValue($objnum); $dict->{O}->{value} = $self->{O}; $dict->{U}->{value} = $self->{U}; # Create a brand new instance my $pkg = ref $self; $doc->{crypt} = $pkg->new($doc, $opass, $upass, 0) || die "$CAM::PDF::errstr\n"; return $doc->{crypt}; }
Also (when I changed the module back to bog-standard 40bit encryption, if I set the user password and owner password differently, the content seems to vanish from the pdf (it's the same size, and the passwords are accepted, but there's nothing on the page.) The simple 1 page pdf in question was created using pdf::api2

Any clues?

The encryption isn't much use at 40bits and neither is not being able to have seperate user and owner passwords, so I'd really like to get this fixed! I'm willing to put some time into it, but could use some help, thanks!

Joe
Direct Responses: 9120 | Write a response
Posted on 2008-10-24 05:45:48-07 by cdolan in response to 9089
Re: 128 bit pdf encryption (and password bug)
I just wanted to say that I've read this and it's a known problem. I've been meaning to address it for a while (I made some good progress over the summer but didn't nail it completely) but I don't have time this month. Feel free to email me directly, as this feature is my #1 priority for this library. I'd love to see some sample, problem PDFs.
Direct Responses: 9128 | Write a response
Posted on 2008-10-24 23:41:04-07 by joe312213 in response to 9120
Re: 128 bit pdf encryption (and password bug)
Hi,

I've been busy trying to fix it myself. Made some progress. Fixed the 40bit implementation for a start, so now user and owner passwords can be different! (meaning you can actually make use of the user permissions now), I've also managed to get 128bit encryption being written and reread by the library (I can extract text from pages faithfully), but so far Adobe Reader accepts the passwords but displays a blank page... I'm close!

Basically how I tackled it was to go back to the pdf spec and implement each algorithm 3.1 - 3.7 as the spec describes it. One thing I noticed was you don't implement step 4 or 3.5 in your code (you do the xor on the key for all 20 RC4 calls). I was doing this, but Reader wouldn't accept the passwords. I swapped back in your _compute_u sub and it accepted the passwords (but displayed a blank page..). I'll send you my code.
Direct Responses: 11183 | Write a response
Posted on 2009-07-17 20:23:59-07 by davelove in response to 9128
Re: 128 bit pdf encryption (and password bug)
Hey Guys, I'm working on something that could really benefit from this. I was wondering what progress has been made since that last post (if any)? I'd also be really interested in the code for the 40bit implementation that does allow different user/owner passwords if no progress has been made on anything better.
Direct Responses: Write a response