Cryptor for RNCryptor.
| 81 | |
| 82 | |
| 83 | class RNCryptor(object): |
| 84 | """Cryptor for RNCryptor.""" |
| 85 | |
| 86 | SALT_SIZE = 8 |
| 87 | |
| 88 | def pre_decrypt_data(self, data): |
| 89 | """Handle data before decryption.""" |
| 90 | data = to_bytes(data) |
| 91 | return data |
| 92 | |
| 93 | def post_decrypt_data(self, data): |
| 94 | """Remove useless symbols which appear over padding for AES (PKCS#7).""" |
| 95 | data = data[:-bord(data[-1])] |
| 96 | return to_str(data) |
| 97 | |
| 98 | def decrypt(self, data, password): |
| 99 | """Decrypt `data` using `password`.""" |
| 100 | data = self.pre_decrypt_data(data) |
| 101 | password = to_bytes(password) |
| 102 | |
| 103 | n = len(data) |
| 104 | |
| 105 | version = data[0] |
| 106 | options = data[1] |
| 107 | encryption_salt = data[2:10] |
| 108 | hmac_salt = data[10:18] |
| 109 | iv = data[18:34] |
| 110 | cipher_text = data[34:n - 32] |
| 111 | hmac = data[n - 32:] |
| 112 | |
| 113 | encryption_key = self._pbkdf2(password, encryption_salt) |
| 114 | hmac_key = self._pbkdf2(password, hmac_salt) |
| 115 | |
| 116 | if not compare_in_constant_time(self._hmac(hmac_key, data[:n - 32]), hmac): |
| 117 | raise DecryptionError("Bad data") |
| 118 | |
| 119 | decrypted_data = self._aes_decrypt(encryption_key, iv, cipher_text) |
| 120 | |
| 121 | return self.post_decrypt_data(decrypted_data) |
| 122 | |
| 123 | def pre_encrypt_data(self, data): |
| 124 | """Do padding for the data for AES (PKCS#7).""" |
| 125 | data = to_bytes(data) |
| 126 | aes_block_size = AES.block_size |
| 127 | rem = aes_block_size - len(data) % aes_block_size |
| 128 | return data + bchr(rem) * rem |
| 129 | |
| 130 | def post_encrypt_data(self, data): |
| 131 | """Handle data after encryption.""" |
| 132 | return data |
| 133 | |
| 134 | def encrypt(self, data, password): |
| 135 | """Encrypt `data` using `password`.""" |
| 136 | data = self.pre_encrypt_data(data) |
| 137 | password = to_bytes(password) |
| 138 | |
| 139 | encryption_salt = self.encryption_salt |
| 140 | encryption_key = self._pbkdf2(password, encryption_salt) |