Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Sat, 18 Mar 2023 16:09:09 +0000
From: Gonn Zerg <>
To: "" <>
Subject: Cracking 1Password8 iOS password. How to use JTR if 1password2john
 isn't suited for my case?

Hi all,

I’m trying to format this as best as I can for the mailing list, I
apologize in advance if it doesn’t meet standards.

I’m looking for advice on how to achieve this using JTR. I have
tried passing my .sqlite file to 1password2john but it doesn’t
appear to be compatible. The account only exists in iOS so I can’t
obtain a macOS or Windows database.

So, I’ve written a script in Python that goes through the same
process 1Password goes through to generate the AUK. I do this
for each password in a dictionary.
I would like to know how the following process could be achieved
using JTR. Or maybe this method is the wrong way to go about this.

I relied heavily on this repository

So these things I know or have from a backup of the device:
- secret Key (version, account id, secret)
- email
- algorithm
- iterations
- salt
- encrypted sqlite database (keysets, account, vaults, etc.)

1. With this I then get the HKDF salt:

hkdf_salt = HKDF(ikm=p2s, len=32, salt=email, hash=SHA256, count=1, info=algorithm)

2. Then the derived password key using the HKDF salt:

password_key = PBKDF2(sha256, password, salt=hkdf_salt, iterations=p2c, 32 bytes)

3. Then the HKDF secret key:

hkdf_key = HKDF(ikm=secret, len=32, salt=AcctID, hash=SHA256, count=1, info=version)

4. Then XOR the password key and the HKDF secret key:

auk = bytes(a ^ b for a, b in zip(password_key, hkdf_key))

5. Then I check if the resulting auk is valid by trying to decrypt and verify the data in the symmetric key:

C =, AES.MODE_GCM, enc_sym_key_iv, mac_len=16)
        PT_enc_sym_key = C.decrypt_and_verify(enc_sym_key_data[:-16], enc_sym_key_data[-16:])
        if PT_enc_sym_key is not None:
                jwk_loaded = json.loads(jwk_json)
                decrypted_kid = jwk_loaded['kid']
                if(decrypted_kid == keyset_uuid):
                    # Found password!
    except ValueError:

I did manage to divide the dictionary into chunks and divide it into 12
processes which was better than my first copy/paste Apple Shortcut.

After attempting this with a new 1Password account on another iOS
device, getting the data needed from the backup and going through a
wordlist that contained the correct password I managed to confirm that
this works and it's very likely that it will work on the main device.

So, how can I do better?

I tried to optimize the code bit by bit and I understand there's
plenty more to improve in it. However, I'd like to move to doing
something like this on an environment that would make this a lot
faster or more efficient. I know I won't be able to code more
efficient solutions than the ones already out there by experts, even
if I wanted to reinvent the wheel.

I started to feel the lack of optimization in my solution when John
The Ripper output a wordlist in the almost hundreds of millions of
lines from a set of rules I thought could contain the right password
but no luck yet. I know I have to grow the list even more but optimize
my approach even more. I would appreciate any help pointing me in the
right direction.

Thank you for reading me!

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.