首页
论坛
专栏
课程

[原创]Adobe Acrobat 9 Pro“用户口令”加密原理分析

2010-11-23 23:06 19379

[原创]Adobe Acrobat 9 Pro“用户口令”加密原理分析

2010-11-23 23:06
19379
                  
                   Adobe Acrobat 9 Pro“用户口令”加密原理分析 

                           天易love      2010-11-23

    网上能搜到的关于pdf文件加密原理的文章很少,即使有也只是9.0版本以前的加密分析,由于现在大多数pdf口令破解工具对9.0以上版本加密的文件束手无策,所以这次仅对9.0版本以上的用户口令(文件打开口令)的加密简单讲一下原理,由于分析时间很短,如有错误敬请指正。
用户口令的概念,当你在Adobe Acrobat 9 Pro的“安全”菜单中选择“使用口令加密”,并在”兼容性”下拉列表框中选择“Acrobat 9.0和更高版本”,然后设置打开文件的口令,此时你设置的就是用户口令,以后如果你忘记了这个口令,你将无法打开该文件。通过以下的加密原理分析,你将会明白为什么只有穷举的办法才能破解,从而对pdf文件加密的安全性有一个更深刻的认识。一些有关pdf文件格式的内容你可以参考网上相关资料,在此不再赘述。
     9.0以上版本加密的算法大致有:sha256、类aes算法;涉及Pdf文件格式中有关标记有/U、/UE、/O、/OE,这些标记具体叫什么名字我觉得与加密原理关系不大。

    为了表述方便,我定义了一些符号:
encodeOfFakeAes();decodeOfFakeAes();sha256();key_expand();keyarrays_handle();
1st8BytesOfLastline_Of_U;
2nd8BytesOfLastline_Of_U;
1stTwolinesOf_U;
1st8BytesOfLastline_Of_O;
2nd8BytesOfLastline_Of_O;
1stTwolinesOf_O;
32BytesOf_UE;
32BytesOf_OE;
keyOriginal; (32字节)
keyarrays;(256字节)
decryptkeyarrays;(256字节)
globalkeyOriginal; (32字节)
decrypGlobaltkeyarrays;(256字节)
   这里each line表示16字节,/U和/O都是3行、/UE、/OE都是2行,如有多出来几个字节,那是因为其中存在字节$5c的缘故,解密过程中不起作用。
 decodeOfFakeAes (32BytesOf_OE)=decodeOfFakeAes (32BytesOf_UE) (条件1)
 sha256(password+1st8BytesOfLastline_Of_U)= 1stTwolinesOf_U;  (条件2)
sha256(passwword+1st8BytesOfLastline_Of_O+U)=1stTwolinesOf_O  (条件3)

  keyOriginal =sha256(password+2nd8BytesOfLastline_Of_U);   
keyarrays=key_expand(keyOriginal);扩展成$100字节(256字节即16进制编译器中显示16 lines,每行16字节);
decryptkeyarrays=keyarrays_handle(keyarrays);将刚才扩展生成的keyarrays再处理一下生成最终decodeOfFakeAes()函数解密需要的密钥数组decryptkeyarrays.
  globalkeyOriginal= decodeOfFakeAes (32BytesOf_OE)
或globalkeyOriginal= decodeOfFakeAes (32BytesOf_UE)
这个globalkeyOriginal经过key_expand()和keyarrays_handle();两次函数处理后得到的decrypGlobaltkeyarrays是用来解密文件内其他对象时用到的密钥数组,解密其他对象时都是用这个decrypGlobaltkeyarrays,唯一不同的是每次文件内待解密对象数据的首字节位置之前的16个字节,这是作为decodeOfFakeAes()函数的初始异或值,由于decodeOfFakeAes()每轮解密得到16字节还要与上一轮的密文异或才是最终的明文而首轮异或的对象就是这16个字节。
 
    
 
 举个例子说明一下如上图,从中我们可以提取出:
/U:
F1 8F 68 04 9C CB 5C FC 00 6B 05 D4 4F CF EC 5B
FA 12 15 BD 78 55 40 27 2D 03 E2 5F 9B 7F 71 8A
38 D5 9B E3 BD 93 84 FD DB D7 5A 0F 08 8B DF D2                                 
/UE:
3A D4 6E 69 1F 25 19 53 26 AC 74 7C E1 D7 1E FA
07 02 31 34 79 E9 70 86 94 5D D6 CA E2 99 8B 36
/O:
BA 8E FC D2 07 F8 C1 94 14 4E A6 F7 58 13 5A 8B
EC C8 89 0C 25 A4 AE 3C 41 49 AF 92 08 00 31 BB
64 C4 40 E5 4D B6 A0 1C 65 32 F7 FD 8D 41 67 30
/OE:
72 30 57 D0 E9 6E 46 42 A2 65 34 A0 D7 93 E3 B2
B3 02 77 26 5E 0E 18 9B 51 E4 51 CD A5 72 CE 69
注:该文件打开口令password是aaa即16进制616161
首先验证sha256(passwword+1st8BytesOfLastline_Of_U)= 1stTwolinesOf_U; 
显然:Sha256(61616138D59BE3BD9384FD)的值是:
f18f68049ccb5cfc006b05d44fcfec5bfa1215bd785540272d03e25f9b7f718a
其次验证:
sha256(passwword+1st8BytesOfLastline_Of_O+U)= 1stTwolinesOf_O;
即对16进制串:616161+64C440E54DB6A01C+ F1 8F 68 04 9C CB 5C FC 00 6B 05 D4 4F CF EC 5B FA 12 15 BD 78 55 40 27 2D 03 E2 5F 9B 7F 71 8A
38 D5 9B E3 BD 93 84 FD DB D7 5A 0F 08 8B DF D2求sha256
显然值为:
ba8efcd207f8c194144ea6f758135a8becc8890c25a4ae3c4149af92080031bb
最后验证decodeOfFakeAes (32BytesOf_OE)=decodeOfFakeAes (32BytesOf_UE):
先用公式sha256(password+2nd8BytesOfLastline_Of_U) 求keyOriginal
Sha256(616161+ DB D7 5A 0F 08 8B DF D2)=
7224c3692572ba7640c517567619d161e6e160621d1aef3b5f8a8259d13ffb3c
 所以keyOriginal就是:
7224c3692572ba7640c517567619d161e6e160621d1aef3b5f8a8259d13ffb3c
接着用key_expand(keyOriginal)扩展密钥得到keyarrays;

扩展后变为256字节:
04865620  0E 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00  
04865630  72 24 C3 69 25 72 BA 76 40 C5 17 56 76 19 D1 61 //这2行就是keyOriginal
04865640  E6 E1 60 62 1D 1A EF 3B 5F 8A 82 59 D1 3F FB 3C  
04865650  06 2B 28 57 23 59 92 21 63 9C 85 77 15 85 54 16  
04865660  BF 76 40 25 A2 6C AF 1E FD E6 2D 47 2C D9 D6 7B   
04865670  31 DD 09 26 12 84 9B 07 71 18 1E 70 64 9D 4A 66  
04865680  FC 28 96 16 5E 44 39 08 A3 A2 14 4F 8F 7B C2 34  
04865690  14 F8 11 55 06 7C 8A 52 77 64 94 22 13 F9 DE 44   
048656A0  81 B1 8B 0D DF F5 B2 05 7C 57 A6 4A F3 2C 64 7E  
048656B0  6D BB E2 58 6B C7 68 0A 1C A3 FC 28 0F 5A 22 6C  
048656C0  F7 0F 18 5D 28 FA AA 58 54 AD 0C 12 A7 81 68 6C   
048656D0  71 FE B2 04 1A 39 DA 0E 06 9A 26 26 09 C0 04 4A   
048656E0  F6 B5 EA 8B DE 4F 40 D3 8A E2 4C C1 2D 63 24 AD  
048656F0  AA C8 27 DC B0 F1 FD D2 B6 6B DB F4 BF AB DF BE  
04865700  FE D7 74 25 20 98 34 F6 AA 7A 78 37 87 19 5C 9A   
04865710  3E 82 9F CB 8E 73 62 19 38 18 B9 ED 87 B3 66 53   

     然后用keyarrays_handle(keyarrays)求decryptkeyarrays这个就是decodeOfFakeAes()最终解密时用的key矩阵了,具体步骤是先利用如下伪代码对除第一、二、最后一行外的所有双字依次进行处理,而后第2行与最后一行、第3行与倒数第2行互换,依次类,这样得到了key矩阵就可以进行解密运算了。
  t1 = 2 * *(_DWORD *)p & 0xFEFEFEFE ^ ((*(_DWORD *)p & 0x80808080) - ((*(_DWORD *)p & 0x80808080u) >> 7)) & 0x1B1B1B1B;
      t2 = 2 * t1 & 0xFEFEFEFE ^ ((t1 & 0x80808080) - ((t1 & 0x80808080) >> 7)) & 0x1B1B1B1B;
      t3 = 2 * t2 & 0xFEFEFEFE ^ ((t2 & 0x80808080) - ((t2 & 0x80808080) >> 7)) & 0x1B1B1B1B;
      t4 = *(_DWORD *)p ^ t3;
      t5 = rol(t2 ^ t4, 16);
      t6 = rol(t1 ^ t4, 8);
      t4 = rol(t4, 8);
      *(_DWORD *)p = t1 ^ t2 ^ t3 ^ t4 ^ t6 ^ t5;
最终的密钥矩阵:
04992EC0  0E 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00   
04992ED0  3E 82 9F CB 8E 73 62 19 38 18 B9 ED 87 B3 66 53   
04992EE0  27 FA 5D F8 9C FF 7C 65 7F 5A 88 32 4F 07 24 34   
04992EF0  51 60 F5 5D 2E 56 BF A9 9B 79 09 19 FC E7 76 18   
04992F00  29 DA 71 A0 BB 05 21 9D E3 A5 F4 57 30 5D AC 06   
04992F10  BF 49 0E C1 7F 36 4A F4 B5 2F B6 B0 67 9E 7F 01  
04992F20  AF 50 21 63 92 DF 50 3D 58 A0 D5 CA D3 F8 58 51  
04992F30  F1 89 A6 B2 C0 7F 44 35 CA 19 FC 44 D2 B1 C9 B1   
04992F40  B8 72 C5 B9 3D 8F 71 5E CA 7F 85 F7 8B 58 8D 9B   
04992F50  5C 2C 12 CA 31 F6 E2 87 0A 66 B8 71 18 A8 35 F5   
04992F60  3E 75 FC E3 85 FD B4 E7 F7 F0 F4 A9 41 27 08 6C   
04992F70  93 2E 36 48 6D DA F0 4D 3B 90 5A F6 12 CE 8D 84   
04992F80  5C F6 E0 E6 BB 88 48 04 72 0D 40 4E B6 D7 FC C5   
04992F90  10 32 9A EA FE F4 C6 05 56 4A AA BB 29 5E D7 72   
04992FA0  EB EF 67 66 E7 7E A8 E2 C9 85 08 4A C4 DA BC 8B   
04992FB0  72 24 C3 69 25 72 BA 76 40 C5 17 56 76 19 D1 61
利用此key,对32BytesOf_OE进行解密得到globalkeyOriginal;
decodeOfFakeAes (32BytesOf_OE)的返回值globalkeyOriginal是:
 DA 2D 99 D0 57 8F 19 73 06 44 AB 1B DA 19 55 F3   
47 94 11 0F 6E D2 FE D4 2F 8A 44 26 67 AA A3 55  
同样decodeOfFakeAes (32BytesOf_UE)的结果也是:
DA 2D 99 D0 57 8F 19 73 06 44 AB 1B DA 19 55 F3   
47 94 11 0F 6E D2 FE D4 2F 8A 44 26 67 AA A3 55
条件1最终成立,这个解密的结果globalkeyOriginal通过类似上面的方法扩展成256字节后就可以用来解密其他加密对象了。
这个所谓的aes虽然是256位密钥,但是解密的分组却是128bit,而且是优化过的,扩展后所谓的Nb也不符合规定,所有函数实现代码都在ccme_base.dll内。
转帖请注明原创于看雪论坛,谢谢!


2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!

上传的附件:
最新回复 (35)
nxxtchao 2010-11-23 23:17
2
0
向高手学习,向高手致敬。
gkdark 1 2010-11-24 03:40
3
0
这个,必须先顶后看.把板凳坐稳先,鄙视楼上抢我沙发!
Sefen 2010-11-24 10:03
4
0
向高手致敬。
exile 1 2010-11-24 10:08
5
0
只能膜拜  无法学习
zhuwg 11 2010-11-24 13:50
6
0
只能膜拜,实力太强了。学不会
我们闪了 2010-11-24 20:27
7
0
膜拜大侠
夜听风雨 2010-11-24 22:11
8
0
学习学习  谢谢楼主分享
StudyRush 3 2010-11-24 22:22
9
0
看着别人的文章加精,自己感觉努力的还不够。
xmyicai 2010-11-24 23:37
10
0
很强大,静而观之
王者之剑 1 2010-11-25 01:08
11
0
现在用这个加密文档的人也多
adomore 2010-11-25 08:10
12
0
只能膜拜,无法学习!
cooooldog 2010-11-25 08:54
13
0
PDF文件7.0/8.0的打开权限的密码也同样不好破解吧...

难道可以直接remove?

salwtp 2010-11-25 08:55
14
0
膜拜一下吧 太强大了。。。。
天易love 18 2010-11-25 09:34
15
0
看看pdf的开发人员名单你就知道直接remove是对他们的侮辱。
仙果 19 2010-11-25 11:45
16
0
一直没有分析过,PDF的加解密,谢谢楼主共享了
Yslf枫 2010-11-25 11:50
17
0
UP,太高深了,感谢分享,只能支持了。
zylzylzylzyl 2010-11-25 20:34
18
0
分析的很透彻,学习一下。不过有很多地方看不懂。
rjchen 2010-11-26 10:34
19
0
进来学习了啊
wdww 2010-11-26 14:28
20
0
膜拜完了,接着学习
gjden 12 2010-11-26 18:08
21
0
先顶,再学习...
小P孩儿 2010-11-27 07:16
22
0
楼主一定很厉害!关注
龙尐 2010-11-27 11:12
23
0
关注
一鸿 2010-11-27 13:01
24
0
请问密钥矩阵什么意思?谢谢
天易love 18 2010-11-27 14:29
25
0

我说的密钥矩阵横着的一行16字节就是上图的竖着的4列,把2行扩展到15行(第一行不算),应该是标准的扩展,SBOX,RCON常数都没有变,只是扩展完没有直接加解密,又处理了一下。
上传的附件:
qwangwei 2010-11-28 10:43
26
0
哎!看不懂只能膜拜啊!
webwizard 2010-12-3 04:03
27
0
关注一下。膜拜大拿。
yyue贤 2010-12-9 22:25
28
0
真的对楼主只有无穷的膜拜中。
scientist 2010-12-10 09:44
29
0
For me, it's way too difficult to understand.
vsax 2010-12-14 01:11
30
0
连看都看不懂,致敬吧。
reggie 2010-12-14 15:30
31
0
。。。要晕了,膜拜楼主
lzgxw 2011-10-20 09:26
32
0
努力看懂中。。。。。。
天易love 18 2011-10-20 12:30
33
0
终于有人识货了。整天讲论坛坏话的人,不知道什么是好东西,太可悲了,有时一句话、一段文字可以让你受益终身。不能永远当菜鸟吧?这得靠你自己去发现!
madsys 2012-4-20 16:31
34
0
这个算法是公开的,不过实现上可能会有差异。
请问楼主是否分析过它的算法有无简化或者漏洞?
天易love 18 2012-4-20 16:37
35
0
不知道是公开的,所以没有比较,很久以前练手的。
大眼睛 2012-4-26 17:55
36
0
只能膜拜,实力太强了。学不会
游客
登录 | 注册 方可回帖
返回