import io import logging from struct import unpack logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) # https://msdn.microsoft.com/en-us/library/dd926359(v=office.12).aspx def _parse_encryptionheader(blob): (flags,) = unpack("<I", blob.read(4)) # if mode == 'strict': compare values with spec. (sizeExtra,) = unpack("<I", blob.read(4)) (algId,) = unpack("<I", blob.read(4)) (algIdHash,) = unpack("<I", blob.read(4)) (keySize,) = unpack("<I", blob.read(4)) (providerType,) = unpack("<I", blob.read(4)) (reserved1,) = unpack("<I", blob.read(4)) (reserved2,) = unpack("<I", blob.read(4)) cspName = blob.read().decode("utf-16le") header = { "flags": flags, "sizeExtra": sizeExtra, "algId": algId, "algIdHash": algIdHash, "keySize": keySize, "providerType": providerType, "reserved1": reserved1, "reserved2": reserved2, "cspName": cspName, } return header # https://msdn.microsoft.com/en-us/library/dd910568(v=office.12).aspx def _parse_encryptionverifier(blob, algorithm: str): (saltSize,) = unpack("<I", blob.read(4)) salt = blob.read(16) encryptedVerifier = blob.read(16) (verifierHashSize,) = unpack("<I", blob.read(4)) if algorithm == "RC4": encryptedVerifierHash = blob.read(20) elif algorithm == "AES": encryptedVerifierHash = blob.read(32) else: raise ValueError("Invalid algorithm: {}".format(algorithm)) verifier = { "saltSize": saltSize, "salt": salt, "encryptedVerifier": encryptedVerifier, "verifierHashSize": verifierHashSize, "encryptedVerifierHash": encryptedVerifierHash, } return verifier def _parse_header_RC4CryptoAPI(encryptionHeader): _flags = encryptionHeader.read(4) # TODO: Support flags (headerSize,) = unpack("<I", encryptionHeader.read(4)) logger.debug(headerSize) blob = io.BytesIO(encryptionHeader.read(headerSize)) header = _parse_encryptionheader(blob) logger.debug(header) # NOTE: https://learn.microsoft.com/en-us/openspecs/office_file_formats/ms-offcrypto/36cfb17f-9b15-4a9b-911a-f401f60b3991 keySize = 0x00000028 if header["keySize"] == 0 else header["keySize"] blob = io.BytesIO(encryptionHeader.read()) verifier = _parse_encryptionverifier(blob, "RC4") # TODO: Fix (cf. ooxml.py) logger.debug(verifier) info = { "salt": verifier["salt"], "keySize": keySize, "encryptedVerifier": verifier["encryptedVerifier"], "encryptedVerifierHash": verifier["encryptedVerifierHash"], } return info
Memory