Adobe Acrobat 9 Pro "User Password" encryption principle analysis
Tian Yi love 2010-11-23
There are very few articles on pdf file encryption principles that can be found on the Internet. Even if there is only an analysis of encryption in versions earlier than 9.0, most pdf password cracking tools are helpless to files encrypted in Versions later than 9.0, this time, we will only briefly describe the principle of password encryption for users later than version 9.0. Due to the short analysis time, please correct me if any error occurs.
The concept of user password. When you select "encrypt with password" in the "Security" menu of Adobe Acrobat 9 Pro ", select "Acrobat 9.0 and later" from the "compatibility" drop-down list box, and set the password for opening the file. At this time, you set the user password. If you forget this password, you cannot open the file. Through the analysis of the following encryption principles, you will understand why only a poor solution can be used to crack, so as to have a deeper understanding of the security of PDF file encryption. For more information about the PDF file format, see relevant online materials.
The encryption algorithms for Versions later than 9.0 are roughly sha256 and aes-like. They involve the/U,/UE,/O,/OE, I think the specific names of these tags have little to do with the encryption principle.
For ease of expression, I have defined some symbols:
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 bytes)
Keyarrays; (256 bytes)
Decryptkeyarrays; (256 bytes)
GlobalkeyOriginal; (32 bytes)
DecrypGlobaltkeyarrays; (256 bytes)
Here, each line indicates 16 bytes, And/U and/O are both 3 rows./UE and/OE are both 2 rows. If there are several more bytes, it is because of the existence of the byte $ 5c, which does not work during decryption.
DecodeOfFakeAes (32BytesOf_OE) = decodeOfFakeAes (32BytesOf_UE) (condition 1)
Sha256 (password + 1st8BytesOfLastline_Of_U) = 1stTwolinesOf_U; (condition 2)
Sha256 (passwword + 1st8BytesOfLastline_Of_O + U) = 1stTwolinesOf_O (Condition 3)
KeyOriginal = sha256 (password + 2nd8BytesOfLastline_Of_U );
Keyarrays = key_expand (keyOriginal); extended to $100 bytes (256 Bytes: 16 lines displayed in the hexadecimal compiler, 16 bytes per line );
Decryptkeyarrays = keyarrays_handle (keyarrays); process the extended keyarrays and generate the final decodeOfFakeAes () function to decrypt the required key array decryptkeyarrays.
GlobalkeyOriginal = decodeOfFakeAes (32BytesOf_OE)
Or globalkeyOriginal = decodeOfFakeAes (32BytesOf_UE)
This globalkeyOriginal is obtained through the key_expand () and keyarrays_handle () functions. The decrypGlobaltkeyarrays obtained after two function operations are the key array used to decrypt other objects in the file, this decrypGlobaltkeyarrays is used to decrypt other objects. The only difference is that 16 bytes before the first byte of the object data to be decrypted in each file, which is used as decodeOfFakeAes () the initial variance or value of the function, because decodeOfFakeAes () each round of decryption results in 16 bytes that are different from the ciphertext in the previous round or that is the final plaintext, while the first round of conversion is the 16 bytes.
For example, we can extract the following information:
/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
Note: The password for Opening this file is aaa, that is, hexadecimal 616161
First, verify that sha256 (passwword + 1st8BytesOfLastline_Of_U) = 1stTwolinesOf_U;
Obviously: the value of Sha256 (616138d59be3bd9384fd) is:
Bytes
Second Verification:
Sha256 (passwword + 1st8BytesOfLastline_Of_O + U) = 1stTwolinesOf_O;
Hexadecimal string: 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 evaluate sha256
Apparently the value is:
Ba8efcd207f8c194144ea6f758135a8becc8890c25a4ae3c4149af92080031bb
Finally, verify decodeOfFakeAes (32BytesOf_OE) = decodeOfFakeAes (32BytesOf_UE ):
Calculate the keyOriginal using the formula sha256 (password + 2nd8BytesOfLastline_Of_U ).
Sha256 (616161 + DB D7 5A 0F 08 8B DF D2) =
Bytes
So keyOriginal is:
Bytes
Then, use the key_expand (keyOriginal) Extension key to obtain the keyarrays;
Extended to 256 Bytes:
04865620 0E 00 00 00 08 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 // these two rows are 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 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
Then, use keyarrays_handle (keyarrays) to calculate decryptkeyarrays. This is the key matrix used for the Final decryption of decodeOfFakeAes, the specific step is to use the following pseudo code to process all the double characters except the first, second, and last lines in sequence, and then swap the last 2nd lines with the last line, 3rd lines with the last 2nd lines, class in sequence to obtain the key matrix for decryption.
T1 = 2 ** (_ DWORD *) p & 0 xfefefefefe ^ (* (_ DWORD *) p & 0x80808080)-(* (_ DWORD *) p & 0x80808080u)> 7) & 0x1B1B1B1B;
T2 = 2 * t1 & 0 xFEFEFEFE ^ (t1 & 0x80808080)-(t1 & 0x80808080)> 7) & 0x1B1B1B1B;
T3 = 2 * t2 & 0 xFEFEFEFE ^ (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;
The final key matrix:
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
049