mirror of
https://github.com/KnugiHK/WhatsApp-Chat-Exporter.git
synced 2026-04-29 09:10:52 +00:00
Support Hex key for Crypt15
This commit is contained in:
@@ -110,7 +110,7 @@ def main():
|
|||||||
elif "crypt15" in options.backup:
|
elif "crypt15" in options.backup:
|
||||||
crypt = Crypt.CRYPT15
|
crypt = Crypt.CRYPT15
|
||||||
if os.path.isfile(options.key):
|
if os.path.isfile(options.key):
|
||||||
key = open(options.key, "rb").read()
|
key = open(options.key, "rb")
|
||||||
elif all(char in string.hexdigits for char in options.key):
|
elif all(char in string.hexdigits for char in options.key):
|
||||||
key = bytes.fromhex(options.key)
|
key = bytes.fromhex(options.key)
|
||||||
db = open(options.backup, "rb").read()
|
db = open(options.backup, "rb").read()
|
||||||
|
|||||||
@@ -8,12 +8,16 @@ import requests
|
|||||||
import shutil
|
import shutil
|
||||||
import re
|
import re
|
||||||
import pkgutil
|
import pkgutil
|
||||||
|
import io
|
||||||
|
import hmac
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from bleach import clean as sanitize
|
from bleach import clean as sanitize
|
||||||
from markupsafe import Markup
|
from markupsafe import Markup
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from mimetypes import MimeTypes
|
from mimetypes import MimeTypes
|
||||||
|
from hashlib import sha256
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import zlib
|
import zlib
|
||||||
from Crypto.Cipher import AES
|
from Crypto.Cipher import AES
|
||||||
@@ -58,25 +62,36 @@ def brute_force_offset():
|
|||||||
yield iv, iv + 16, db
|
yield iv, iv + 16, db
|
||||||
|
|
||||||
|
|
||||||
def extract_encrypted_key(keyfile):
|
def _generate_hmac_of_hmac(key_stream):
|
||||||
from hashlib import sha256
|
|
||||||
import hmac
|
|
||||||
key_stream = b""
|
|
||||||
for byte in javaobj.loads(keyfile):
|
|
||||||
key_stream += byte.to_bytes(1, "big", signed=True)
|
|
||||||
key = hmac.new(
|
key = hmac.new(
|
||||||
hmac.new(b'\x00' * 32, key_stream, sha256).digest(),
|
hmac.new(
|
||||||
|
b'\x00' * 32,
|
||||||
|
key_stream,
|
||||||
|
sha256
|
||||||
|
).digest(),
|
||||||
b"backup encryption\x01",
|
b"backup encryption\x01",
|
||||||
sha256
|
sha256
|
||||||
)
|
)
|
||||||
return key.digest()
|
return key.digest()
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_encrypted_key(keyfile):
|
||||||
|
key_stream = b""
|
||||||
|
for byte in javaobj.loads(keyfile):
|
||||||
|
key_stream += byte.to_bytes(1, "big", signed=True)
|
||||||
|
|
||||||
|
return _generate_hmac_of_hmac(key_stream)
|
||||||
|
|
||||||
|
|
||||||
def decrypt_backup(database, key, output, crypt=Crypt.CRYPT14):
|
def decrypt_backup(database, key, output, crypt=Crypt.CRYPT14):
|
||||||
if not support_backup:
|
if not support_backup:
|
||||||
return 1
|
return 1
|
||||||
|
if isinstance(key, io.IOBase):
|
||||||
|
key = key.read()
|
||||||
|
if crypt is not Crypt.CRYPT15:
|
||||||
|
t1 = key[30:62]
|
||||||
if crypt is not Crypt.CRYPT15 and len(key) != 158:
|
if crypt is not Crypt.CRYPT15 and len(key) != 158:
|
||||||
raise ValueError("The key file must be 158 bytes")
|
raise ValueError("The key file must be 158 bytes")
|
||||||
t1 = key[30:62]
|
|
||||||
if crypt == Crypt.CRYPT14:
|
if crypt == Crypt.CRYPT14:
|
||||||
if len(database) < 191:
|
if len(database) < 191:
|
||||||
raise ValueError("The crypt14 file must be at least 191 bytes")
|
raise ValueError("The crypt14 file must be at least 191 bytes")
|
||||||
@@ -99,11 +114,15 @@ def decrypt_backup(database, key, output, crypt=Crypt.CRYPT14):
|
|||||||
t1 = t2 = None
|
t1 = t2 = None
|
||||||
iv = database[8:24]
|
iv = database[8:24]
|
||||||
db_ciphertext = database[131:]
|
db_ciphertext = database[131:]
|
||||||
|
|
||||||
if t1 != t2:
|
if t1 != t2:
|
||||||
raise ValueError("The signature of key file and backup file mismatch")
|
raise ValueError("The signature of key file and backup file mismatch")
|
||||||
|
|
||||||
if crypt == Crypt.CRYPT15:
|
if crypt == Crypt.CRYPT15:
|
||||||
main_key = extract_encrypted_key(key)
|
if len(key) == 32:
|
||||||
|
main_key = _generate_hmac_of_hmac(key)
|
||||||
|
else:
|
||||||
|
main_key = _extract_encrypted_key(key)
|
||||||
else:
|
else:
|
||||||
main_key = key[126:]
|
main_key = key[126:]
|
||||||
decompressed = False
|
decompressed = False
|
||||||
|
|||||||
Reference in New Issue
Block a user