当前位置: 首页 > 工具软件 > PoDoFo > 使用案例 >

pdf文件权限的简单原理,VS开发库podofo初步使用去掉权限密码

管玉堂
2023-12-01

wxleasyland@sina.com

2020.5

 

一、pdf文件权限的简单原理

 

PDF的Owner密码=权限口令 , User密码=打开口令

 

对pdf文件设置权限,原理是采用权限口令(owner)对文件进行加密!并不是简单地在文件中设置一个权限标志!

所以去除权限,必须要经过解密这个过程。

 

权限口令 会加密成条目O,放在PDF文件中。

 

权限状态(可否打印,可否复制等) 就是条目P,放在PDF文件中。

 

打开口令 会加密成条目U,放在PDF文件中。

 

条目O+条目P+打开口令 → 可生成全局密钥,采用全局密钥对文件内容进行加密。

 

加密必须要设置权限口令,不一定要设置打开口令。

如果没有设置打开口令,则打开口令采用默认值,通过口令默认值、条目O和条目P,可以得到全局密钥。这样文件内容可以解密!查看器需要进行权限限制。

 

如果有设置打开口令,则需要打开口令才能解密,即需要输入打开密码才能打开PDF文件。

如果打开口令=权限口令(可通过重新计算条目O和条目U来判断),则查看器放开所有权限。

如果打开口令≠权限口令(可通过重新计算条目O和条目U来判断),则查看器进行权限限制。

 

 

二、podofo初步使用

podofo是PDF的开发库。可以在VS下编库使用。初步摸索了一下。

 

helloworld是用PdfStreamedDocument生成文件,再PdfPainter。

 

podofomerge是用PdfMemDocument读入或生成文件,InsertPages或Append方法。

 

podofoencrypt是用PdfVecObjects和PdfParser读入一个文件,  再PdfWriter 和 PdfEncrypt。

 

podofopdfinfo是它自己重写了PdfInfo类,不是采用标准的PdfInfo类。 实际是采用PdfMemDocument。

 

如果参考podofomerge,建一个空文件,再把旧文件(有owner密码)Append进来,写新文件,则出现提示是:删除了很多reference,新文件没有权限限制了!但所有的跳转都没有了,书签还在但跳转没有了,目录也在但跳转也没有了!(因为APPEND后位置不一样了,原有的reference就不准了,只能删掉)。  另外文件变成内部没有压缩的,很大!  这个方法有缺陷,不好。

 

如果参考podofoencrypt,PdfVecObjects和PdfParser读入旧文件(有owner密码), 再PdfWriter写新文件,则成功,新文件没有权限限制了!书签还在,跳转都还在。只是文件变成内部没有压缩的,很大!  用winrar可以压缩这个pdf文件到很小。

 

内部未压缩的pdf文件,可以用acrobat reader打开,再另存,OK,就变成内部压缩的pdf文件了,文件很小。也可以用acrobat打开和另存,这时不仅压缩了,而且还带快速WEB查看功能。

 

这个方法可以,成功!

 

总结来说,就是podofo在打开PDF文件时,会自动解密及解压缩,保存成新文件后,就没权限限制了,再用acrobat reader另存下,使文件变小。

 

上干货:

 

#include "src\podofo.h"

 

#include <stdlib.h>

#include <cstdio>

 

using namespace PoDoFo;

 

#ifdef _HAVE_CONFIG

#include <config.h>

#endif // _HAVE_CONFIG

 

void myconvert( const char* pszInput1,  const char* pszOutput )

{

  PdfVecObjects objects;

    PdfParser     parser( &objects );

 

  printf("Reading file: %s\n", pszInput1 );

    objects.SetAutoDelete( true );

    parser.ParseFile( pszInput1 );

  printf("PdfVecObjects.GetMaxObjectCount(): %ld\n", (long)objects.GetObjectCount() );

  printf("PdfParser.GetEncrypted(): %d\n", parser.GetEncrypted() );

 

 

  printf("************\nPdfWriter: \n"  );

  PdfWriter writer( &parser );

  printf("GetEncrypted(): %d\n", writer.GetEncrypted() );

  printf("GetLinearized(): %d\n", writer.GetLinearized() );

  printf("GetPdfVersionString(): %s\n", writer.GetPdfVersionString() );

  printf("GetWriteMode(): %d\n", writer.GetWriteMode() );  //ePdfWriteMode_Compact=1

 

    printf("Writing file: %s\n", pszOutput );

  writer.Write( pszOutput );

}

 

 

 

int main( int argc, char* argv[] )

{

  char*   pszInput1;

  char*   pszOutput;

 

  if( argc != 3 )

  {

    exit( -1 );

  }

 

  pszInput1 = argv[1];

  pszOutput = argv[2];

 

  try

  {

    myconvert( pszInput1, pszOutput );

  }

  catch( PdfError & e )

  {

      fprintf( stderr, "Error %i occurred!\n", e.GetError() );

      e.PrintErrorMsg();

      return e.GetError();

  }

 

  return 0;

}

 

 

 

好吧,podofo太复杂,我也只会这么多。

 

 类似资料: