0 几个重要概念

全局加密密钥,简称为全局密钥,该全局密钥由加密字典对象和你输入的口令生成,用来生成对象加密密钥。

对象加密密钥,简称为对象密钥,是用来实际加密PDF文件内容的密钥,不同于上篇PDF加密仿真里的全部的对象共用一个密钥不同,PDF文件中每个对象的加密密钥都不一样。

User Password 用户口令。

Owner password 权限口令。

1 PDF文件的加密流程

上一篇文章大致介绍了关于ACROBAT对PDF加密操作和加密后生成的PDF文件中的加密字典对象。同时我们提出了下面的四个问题:

1.         文件的内容是如何被加密的?

2.         加密密钥是如何生成的?

3.         加密字典中的每一项是如何生成的?

4.         加密字典和加密密钥的关系?

第一个问题是我们的最终目的,本文要最终要解决的就是这个问题。而第2,3,4个问题作为第1个问题的分解,在下文中有个清晰地解答。

下面是一个PDF文件加密的大致过程:

1.         选择PDF兼容版本和输入用户口令,权限口令。

2.         根据输入生成加密字典对象。

3.         由输入和加密字典对象生成全局密钥。

4.         由全局密钥生成对象加密密钥。

5.         用对象加密密钥加密对象内容。

2 PDF加密解密流程详解

加密字典对象一般有下面的条目:

/Length 密钥的长度

/Filter 生成密钥的方法,就是前面说的security handler

/O 是由用户口令和权限口令得到的,用来生成密钥和验证输入的权限口令

/P 访问权限的标志

/R 标准加密的(standard security handler)的版本

/U由用户口令生成,用来验证输入的用户口令或权限口令,是否要提醒用户输入密码

/V  可选,用来指明加密的算法。

一般来说这上面的条目是必须的,其它条目具体见PDF规范。这上面的加密字典条目中除了条目O和U之外其它的都可以直接生成。那么接下来我们就来看这两个条目,全局加密密钥,和对象加密密钥的生成过程。

如果你去看PDF规范,在有的步骤会有点迷茫的,相信下面的详细介绍对大家会有所帮助,如果你要实现自己的加密程序,也将给你一个指引。

2.1 生成加密字典和加密密钥

2.1.1 生成条目O

算法3.3

1.         补充或截取权限口令字符串为32个字节。如果输入的口令大于32个字节,那么只保留前32个字节,如果少于32个字节,那么就按下面的字符串补上所缺少的字节数:

<0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x 8a , 0x41,

0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,

0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,

0x 2f , 0x 0c , 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a>

如果没有权限(主)口令,那么就用用户口令替代。

2.      初始化MD5函数并将步骤1产生的结果输入MD5函数。

3.      (版本3或更高)连续做50次:此后输出作为输入新的MD5哈希函数中。

4.      利用这个HASH数列的前面n位创建RC4密钥,对于版本2来说,n始终为5, 但对于版本3或更高版本来说,取决于加密字典中Length的值,为length/8。

5.      按照算法3.2中的第一步由用户口令得到32字节字符串。

6.      将第5步中产生的32位字节字符串用第4步中产生的密钥用RC4算法加密。

7.      (版本3或更高)做19次:用前一次的输出作为下一次的输入进行编码;密钥是由第1步产生的原始密钥的单个字节和循环数和进行XOR(异或)运算得到的。

char Test[32] = 第1步生成的32字符串。

char temKey = Test[32];

unsigned int keyLength = length/8;

for (i = 1; i <=19; i++)

{

for (j = 0; j < keyLength; ++j)

{

tmpKey[j] = fileKey[j] ^ i;

}

rc4InitKey(tmpKey, keyLength, fState);

fx = fy = 0;

for (j = 0; j < 32; ++j)

{

test[j] = rc4EncryptByte(fState, &fx, &fy, test[j]);

}

8.      这32字节字符串即为加密字典对象条目O的值。

图1

2.1.2 得到全局加密密钥

算法2:

1. 补充或截取口令字符串为32个字节。如果输入的口令大于32个字节,那么只保留前32个字节,如果少于32个字节,那么就按下面的字符串补上所缺少的字节数:

<0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x 8a , 0x41,

0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,

0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,

0x 2f , 0x 0c , 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a>

如果用户口令为空,那么就意味着没有用户口令,用这32个字节完全填充。

2.初始化MD5函数并将步骤1产生的结果输入MD5函数。

3.将加密字典O条目输入MD5中。(算法3.3描述O值的产生)。

4.将P条目作为无符号的4字节整数然后将该4字节输入MD5函数。

5.将该PDF文档的ID标识数组的第一个元素(即该PDF文档中trailer字典中ID条目的第一个字符串)输入到函数MD5中。(关于PDF文档ID的介绍见文章“PDF文档ID”)

6. (版本3或更高)如果该文档的metadata不加密,将4字节的0xFFFFFFFF输入哈希函数MD5中。

7.结束散列。

8.(版本3或更高)将前面MD5产生的HASH序列的前n位,也就是加密字典中的Length/8位字串,输入到新的MD5哈希函数中,此后输出作为输入连续再做49次。

9.加密密钥就是这个HASH数列的前面n位,对于版本2来说,n始终为5,对于版本3或更高版本来说,就取决于加密字典中Length的值,n=length/8。

这个算法,是根据用户口令字符串,产生全局加密密钥。

图2

2.1.3 生成条目U

算法4 版本2:

1 按照算法2的方法,基于用户口令字符串生成加密密钥。

2 用上面步骤产生的加密密钥加密按照算法2步骤1生成的32位串。

3 步骤2的输出即为加密字典对象中条目U的值。

算法5 版本3:

1按照算法2的方法,基于用户口令字符串生成加密密钥。

2 初始化MD5 HASH函数并将按照算法2步骤1生成的32位字符串输入该函数。

3 将文件ID数组中的第一个32位ID字串传入MD5函数。

4 用第1步产生的密钥通过RC4算法来加密由步骤3输出的16位字符串。

9.      做19次:用前一次的输出作为下一次的输入进行解码;密钥是由第1步产生的原始密钥的单个字节和循环数和进行XOR(异或)运算得到的。

char Test[32] = 第1步生成的32字符串。

char temKey = Test[32];

unsigned int keyLength = length/8;

for (i = 1; i <=19; i++)

{

for (j = 0; j < keyLength; ++j)

{

tmpKey[j] = fileKey[j] ^ i;

}

rc4InitKey(tmpKey, keyLength, fState);

fx = fy = 0;

for (j = 0; j < 32; ++j)

{

test[j] = rc4EncryptByte(fState, &fx, &fy, test[j]);

}

2.2 生成对象加密密钥并将对象加密

算法3.1 用RC4和AES对数据进行加密算法:

1.获得字符串对象或流对象的对象号(object number)和产生号(generation numer), 如果字符串对象是一个直接对象,则利用其包含该对象的标识符。

2.将对象号和产生号作2进制整数对待,将原始的N字节长的密匙扩展到n+5字节,即将对象号的低3个字节和产生号的低2个字节依次接在前面N字节长的加密K密钥上, 顺序为低字节靠前。(如果密钥的长度为40那么n为5,如果V的值大于1, n的值就为Length除以8。)

3.初始化MD5哈希函数,然后将步骤2产生的字符串输入到MD5中。

4.用前(n+5)个字节,如果N+5>16那么截取前面的16个字节,将这个产生的hash结果作为RC4和AES对称加密算法的密匙来对该字符串或流对象进行加密。

如果是用到AES算法,用到CBC模式。

图 3

3 回答云木的问题

云木的问题是这样,只有设置了权限口令的的PDF文件,是否可以直接从PDF文件中取出某个对象的流?

他想这样的PDF文件应该是不加密的,因为PDF文件的内容是可以看到的,只是设置了一个用来表示权限的串。这是我上篇文章《PDF文件加密仿真》中说的,而且还说了可以有办法去掉这个串或者修改这个串,不过我也有在文章中用红色字体说明PDF文件中内容实际上是加密了的,只是加密密钥可以从加密字典中直接计算出来。

那么这个密钥如何如何计算得到呢?我想由算法3.2和算法3.1就得出答案了。因为没有打开口令,那么直接由上面的32字节加密口令常量串填充,然后根据其它文件中的相关内容得到全局密钥。进而生成对象加密密钥。

4 是否可以直接修改权限设置串

有的人说可以直接修改加密字典中的条目P得到更大的权限,其实不然,因为按照加密算法2,全局加密密钥其中有个输入就是P, 如果P修改了,也不能正确得到加密密钥。你也可以实际试验一下,用 Ultra Edit打开,修改P条目,然后再用PDF reader打开,就会提示你输入口令,因为根据该PDF文件本身是无法得到加密密钥了。

5 本文总结

本文详细地对PDF文件的口令加密做了一个说明,相信你可以利用它来对PDF文件进行口令加密了,当然在一些细节方面你需要查询一下PDF规范。整篇文章采用多种方式来表达,目的只有一个,就是让整个内容显得非常明白容易理解。 在两个比较难懂的地方我用了伪码,我想这也会对你的理解有所帮助。

当然,错误是在所难免的,如果你对文章有什么意见,或者有什么知道,或者你认为怎样会更好,那么我非常希望你能给我来信或者给我评论和留言。

非常感谢!

PDF加密、解密内幕(二)- PDF文件口令加密内幕相关推荐

  1. 【加密解密】对exe文件的加密解密 含源代码》

    //编译环境VS2013#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #includ ...

  2. PDF加密、解密内幕(二) - PDF文件口令加密内幕

    PDF加密.解密内幕(二) - PDF文件口令加密内幕 0 几个重要概念 全局加密密钥,简称为全局密钥,该全局密钥由加密字典对象和你输入的口令生成,用来生成对象加密密钥. 对象加密密钥,简称为对象密钥 ...

  3. IOS之RSA加密解密与后台之间的双向加密详解

    IOS之RSA加密解密与后台之间的双向加密详解 序言 因为项目中需要用到RSA加密,刚开始也是有点乱,这两天也整理的差不多了,希望能帮到大家. 这次先上代码,我想大部分人肯定是着急解决问题,所以不要废 ...

  4. 文件夹加密软件哪个好?文件夹加密软件排行榜

    想要加密文件夹,使用专业的文件夹加密软件可以安全有效地加密电脑文件夹.那么,文件夹加密软件哪个好?文件夹加密软件排行榜了解一下. TOP 1:文件夹加密超级大师 软件亮点:极致安全,5种文件夹加密类型 ...

  5. 文件夹加密软件怎么选?文件夹加密软件盘点

    文件夹是电脑储存数据的重要工具,那么该如何保护文件夹的数据安全呢?使用合适的文件夹加密软件可能是最简单的方法.那么文件夹加密软件该怎么选呢? 文件夹加密超级大师 文件夹加密超级大师可以说是最全能的文件 ...

  6. php 密匙加密解密,带密匙的php加密解密示例分享

    这篇文章主要介绍了php加密解密示例,大家参考使用吧 复制代码 代码如下: /************************************************************* ...

  7. 【Kotlin】加密解密2:DES、AES加密和解密

    文章目录 Api文档 DES加密解密 Base64加密和解密 AES加密解密 DES和AES密钥长度 工作模式和填充模式 对称加密的应用场景 Api文档 https://docs.oracle.com ...

  8. php结合md5的加密解密,php结合md5实现的加密解密方法,php结合md5加密解密_PHP教程...

    php结合md5实现的加密解密方法,php结合md5加密解密 本文实例讲述了php结合md5实现的加密解密方法.分享给大家供大家参考,具体如下: 最近在整理代码发现了一个不错的东西,结合md5的加解密 ...

  9. c语言解密pdf,C语言设计-英文加密解密系统资料.pdf

    昆明理工大学 <程序设计基础>课程 综合设计实践教学课题报告 课程名称: C 语言设计 课题名称: 英文加密解密系统 组长: 学号 姓名 组员: 学号 姓名: 学号 姓名 学院: 专业班级 ...

最新文章

  1. Chapter5_初始化与清理_enum关键字
  2. 2016各大公司校招薪水曝光:年薪28万,这只是零花钱
  3. C结构体工具DirectStruct(综合示例二)
  4. 在线实时大数据平台Storm集成redis开发(分布锁)
  5. zookeeper命令
  6. [转载]流行视频格式讲解
  7. Photoshop Blendmodi in GLSL
  8. 企业网站 源码 e-mail_临汾网站制作,B2B软件哪家好
  9. 字符串includes_字符串操作大全:面试准备和日常编码所需一文打尽
  10. 转SQLSERVER 会不会自动加锁
  11. 8. jQuery 效果 - 动画
  12. 一个校园网络的规划与设计
  13. CMD 命令 复制多级子目录特定文件
  14. 独木桥的c语言程序,独木桥
  15. 没想到一个起点中文网都可以掀起这么大的波澜
  16. AcWing 741. 斐波那契数列
  17. 淘宝直播详细开通方法
  18. Word 题注重新编号
  19. 站在物联网风口 中兴着力构建GIA 的IoT新生态
  20. YoloV4当中的Mosaic数据增强方法(附代码讲解)

热门文章

  1. Python提取excel中指定关键字的单元格
  2. Speedoffice(Excel)如何快速查找并突出高亮显示关键字
  3. 继电器线圈端反向并接二极管的原因
  4. 敏感词过滤 java
  5. 学习Python中turtle模块的基本用法(5:绘制简笔画羊)
  6. ubuntu系统安装nginx
  7. 百度地图开发系列(5):高亮显示省市县级别的行政区域
  8. shell语法入门看着一篇就够了
  9. PDF分割页面怎么实现?这些方法亲测实用
  10. SpringMvc拦截器模板,对token优化