def decryptData(data, password=None, keyLength=None, mode='CBC'): ''' Method added for peepdf ''' decryptedData = '' if keyLength == None: keyLength = len(password) * 8 if keyLength not in [128, 192, 256]: return (-1, 'Bad length key in AES decryption process') iv = list(map(ord, data[:16])) key = list(map(ord, password)) data = data[16:] if len(data) % 16 != 0: data = data[:-(len(data) % 16)] keyExpander = key_expander.KeyExpander(keyLength) expandedKey = keyExpander.expand(key) aesCipher = aes_cipher.AESCipher(expandedKey) if mode == 'CBC': aesMode = cbc_mode.CBCMode(aesCipher, 16) aesMode.set_iv(iv) for i in range(0, len(data), 16): ciphertext = list(map(ord, data[i:i + 16])) decryptedBytes = aesMode.decrypt_block(ciphertext) for byte in decryptedBytes: decryptedData += chr(byte) return (0, decryptedData)
def decrypt_regulation_bin(self, data: bytes) -> bytes: try: # noinspection PyPackageRequirements from aespython import key_expander, aes_cipher, cbc_mode except ImportError: raise ModuleNotFoundError( f"Cannot decrypt `regulation.bin` for Elden Ring without `aespython` package." ) iv = data[:16] encrypted = BinaryReader(data) key_expander_256 = key_expander.KeyExpander(256) expanded_key = key_expander_256.expand(bytearray(self.REGULATION_KEY)) aes_cipher_256 = aes_cipher.AESCipher(expanded_key) aes_cbc_256 = cbc_mode.CBCMode(aes_cipher_256, 16) aes_cbc_256.set_iv(iv) decrypted = b"" while True: chunk = encrypted.read(16) if len(chunk) == 0: # end of file break decrypted_chunk = bytearray( aes_cbc_256.decrypt_block(list(bytearray(chunk)))) decrypted += decrypted_chunk # print(f"{len(decrypted)}") with open("regulation.bin.decrypted", "wb") as f: f.write(decrypted) with open("regulation.bin.decryptednodcx", "wb") as f: f.write(decompress(decrypted[16:])[0]) return decrypted
def encrypt_file(self, in_file_path, out_file_path, password=None): # If a password is provided, generate new salt and create key and iv if password is not None: self.new_salt() self.create_key_from_password(password) else: self._salt = None # If key and iv are not provided are established above, bail out. if self._key is None or self._iv is None: return False # Initialize encryption using key and iv key_expander_256 = key_expander.KeyExpander(256) expanded_key = key_expander_256.expand(self._key) aes_cipher_256 = aes_cipher.AESCipher(expanded_key) aes_cbc_256 = cbc_mode.CBCMode(aes_cipher_256, 16) aes_cbc_256.set_iv(self._iv) # Get filesize of original file for storage in encrypted file try: filesize = os.stat(in_file_path)[6] except: return False with open(in_file_path, 'rb') as in_file: with open(out_file_path, 'wb') as out_file: # Write salt if present if self._salt is not None: out_file.write(self._salt) # Write filesize of original out_file.write(struct.pack('L', filesize)) # Encrypt to eof eof = False while not eof: in_data = in_file.read(16) if len(in_data) == 0: eof = True else: out_data = aes_cbc_256.encrypt_block( bytearray(in_data)) out_file.write(self.fix_bytes(out_data)) self._salt = None return True
def decrypt_file(self, in_file_path, out_file_path, password=None): with open(in_file_path, 'rb') as in_file: # If a password is provided, generate key and iv using salt from file. if password is not None: self._salt = in_file.read(32) self.create_key_from_password(password) # Key and iv have not been generated or provided, bail out if self._key is None or self._iv is None: return False # Initialize encryption using key and iv key_expander_256 = key_expander.KeyExpander(256) expanded_key = key_expander_256.expand(self._key) aes_cipher_256 = aes_cipher.AESCipher(expanded_key) aes_cbc_256 = cbc_mode.CBCMode(aes_cipher_256, 16) aes_cbc_256.set_iv(self._iv) # Read original file size filesize = struct.unpack('L', in_file.read(struct.calcsize('L')))[0] # Decrypt to eof with open(out_file_path, 'wb') as out_file: eof = False while not eof: in_data = in_file.read(16) if len(in_data) == 0: eof = True else: out_data = aes_cbc_256.decrypt_block( list(bytearray(in_data))) # At end of file, if end of original file is within < 16 bytes slice it out. if filesize - out_file.tell() < 16: out_file.write( self.fix_bytes(out_data[:filesize - out_file.tell()])) else: out_file.write(self.fix_bytes(out_data)) self._salt = None return True