def decrypt(raw, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter, page_sz, iv_sz, reserve_sz, hmac_sz): dec = b'SQLite format 3\0' # derive key salt_sz = 16 salt = raw[:salt_sz] key, hmac_key = util.key_derive(salt, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter) # decrypt file header, try with default page size page_sz, reserve_sz = decrypt_page_header(raw, key, salt_sz, page_sz, iv_sz, reserve_sz) if page_sz < 0 or reserve_sz < 0: raise RuntimeError('failed to decide page size or reserve size.') # decrypt pages for i in range(0, int(len(raw) / 1024)): page = util.get_page(raw, page_sz, i + 1) if i == 0: # skip salt page = page[salt_sz:] page_content = page[:-reserve_sz] reserve = page[-reserve_sz:] iv = reserve[:iv_sz] # check hmac hmac_old = reserve[iv_sz:iv_sz + hmac_sz] hmac_new = util.generate_hmac(hmac_key, page_content + iv, i + 1) if not hmac_old == hmac_new: raise RuntimeError('hmac check failed in page %d.' % (i + 1)) # decrypt content page_dec = util.decrypt(page_content, key, iv) dec += page_dec + util.random_bytes(reserve_sz) return dec
def decrypt(raw, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter, page_sz, iv_sz, reserve_sz, hmac_sz): dec = b'SQLite format 3\0' # derive key salt_sz = 16 salt = raw[:salt_sz] key, hmac_key = util.key_derive(salt, password, salt_mask, key_sz, key_iter, hmac_key_sz, hmac_key_iter) # decrypt file header, try with default page size page_sz, reserve_sz = decrypt_page_header(raw, key, salt_sz, page_sz, iv_sz, reserve_sz) if page_sz < 0 or reserve_sz < 0: raise RuntimeError('failed to decide page size or reserve size.') # decrypt pages for i in range(0, int(len(raw) / 1024)): page = util.get_page(raw, page_sz, i + 1) if i == 0: # skip salt page = page[salt_sz:] page_content = page[:-reserve_sz] reserve = page[-reserve_sz:] iv = reserve[:iv_sz] # check hmac hmac_old = reserve[iv_sz:iv_sz+hmac_sz] hmac_new = util.generate_hmac(hmac_key, page_content + iv, i + 1) if not hmac_old == hmac_new: raise RuntimeError('hmac check failed in page %d.' % (i+1)) # decrypt content page_dec = util.decrypt(page_content, key, iv) dec += page_dec + util.random_bytes(reserve_sz) return dec
def fast_stream_decrypt(filename_in: str, password: bytearray, filename_out: str): with open(filename_in, 'rb') as enc, open(filename_out, 'wb', buffering=config.page_sz * 16) as dec: enc_size = os.path.getsize(enc.name) dec.write(config.header) first_page = enc.read(config.page_sz) # derive key salt_sz = 16 salt = first_page[:salt_sz] key, hmac_key = util.key_derive(salt, password, config.salt_mask, config.key_sz, config.key_iter, config.hmac_key_sz, config.hmac_key_iter) # decrypt file header, try with default page size page_sz, reserve_sz = decrypt_page_header(first_page, key, salt_sz, config.page_sz, config.iv_sz, config.reserve_sz) if page_sz < 0 or reserve_sz < 0: raise RuntimeError('failed to decide page size or reserve size.') enc.seek(0) for i in tqdm(range(0, int(enc_size / 1024))): page = enc.read(config.page_sz) if i == 0: page = page[salt_sz:] page_content = page[:-reserve_sz] reserve = page[-reserve_sz:] iv = reserve[:config.iv_sz] dec.write(util.decrypt(page_content, key, iv)) dec.write(util.random_bytes(reserve_sz)) dec.flush()
def decrypt_by_reserve_size(first_page_without_salt, key, iv_sz, reserve_sz): """Decrypt page content using specified reserve size""" reserve = first_page_without_salt[-reserve_sz:] iv = reserve[:iv_sz] return util.decrypt(first_page_without_salt, key, iv)