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