office2john is designed for encrypted files, not files that just have an easily-removable snake-oil protection field. Anyway, here's a quick implementation of the algorithm that they use:
from base64 import b64encode, b64decode
from hashlib import sha512
def hash_password(password, salt, spincount, hash):
result = hash(b64decode(salt) + password.encode('utf_16_le')).digest()
for i in range(spincount):
result = hash(result + struct.pack('<I', i)).digest()
print(hash_password('pwd', '876MLoKTq42+/DLp415iZQ==', 100000, sha512))
I took that test case from LibreOffice.
This doesn't produce the right answer with what you posted, though:
print(hash_password('john', 'DdJzMvZ9KqpGuTrabHJ1eg==', 100000, sha512))
print(hash_password('**john**', 'DdJzMvZ9KqpGuTrabHJ1eg==', 100000, sha512))
The OOXML specification for
hashValue says "This value shall
be compared with the resulting hash value after hashing the user-supplied password
using the algorithm specified by the preceding attributes and parent XML element" and "The hashValue attribute value of
9oN7nWkCAyEZib1RomSJTjmPpCY= specifies that the
user-supplied password must be hashed using the pre-processing defined by the parent
element (if any) followed by the SHA-1 algorithm (specified via the algorithmName
attribute value of SHA-1) and that the resulting hash value must be
9oN7nWkCAyEZib1RomSJTjmPpCY= for the protection to be disabled."
I suspect this difference comes from a parent XML element specifying an algorithm, which you didn't bother to show us. If you want to crack your password and not just remove it, then you need to do two things:
- Account for the extra preprocessing algorithm, if you have one
- Either add functionality to John the Ripper to support sheet protection passwords (which you'll need to keep separate from the existing Office encryption functionality), or write your own cracker based on the algorithm.