PythonでExcelのパスワードを解析する方法
カギをかけたままパスワードを忘れてしまい、Excel を開けなくなった経験はないでしょうか?今回は Python で忘れてしまったパスワードを解析する方法を紹介します。
環境設定
Python から Excel を展開するライブラリとしてmsoffcrypto-toolを使用します。
pip install msoffcrypto-tool
プログラムを実行する
桁数まで忘れてしまった場合を想定して、上限桁数を設定し、その桁に達するまで総当たりで解析する仕組みです。
import string
from itertools import product
import msoffcrypto
import io
import time
decrypted = io.BytesIO()
encrypted = open("target.xlsx", "rb")
detected = ""
file = msoffcrypto.OfficeFile(encrypted)
DIGITS = 12
def generate_passwords(words, repeat):
for i in product(words, repeat=repeat):
yield ''.join(i)
for d in range(DIGITS):
digit = d + 1
passwords = generate_passwords(string.printable, digit)
for password in passwords:
if detected != "":
break
file.load_key(password=password)
try:
file.decrypt(decrypted)
detected = password
print("パスワードは「", password, "」です")
break
except:
pass
print("end")
マルチコアパターン
リソースを見てみると、CPU もメモリもストレージも大きく使用できていなかったので、マルチスレッドでの実行パターンも作成しました。
import string
from itertools import product
import msoffcrypto
import io
import time
import threading
decrypted = io.BytesIO()
encrypted = open("target.xlsx", "rb")
detected = ""
file = msoffcrypto.OfficeFile(encrypted)
DIGITS = 12
def generate_passwords(words, repeat):
for i in product(words, repeat=repeat):
yield ''.join(i)
def challenge_passwords(passwords):
global detected
global file
global decrypted
for password in passwords:
if detected != "":
break
file.load_key(password=password)
try:
file.decrypt(decrypted)
print("パスワードは「", password, "」です")
detected = password
break
except:
pass
threads = []
for d in range(DIGITS):
digit = d + 1
passwords = generate_passwords(string.ascii_lowercase + string.digits, digit)
thread = threading.Thread(target=challenge_passwords, args=(passwords,))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
print("end", detected)