Skip to content

Commit

Permalink
Fix accessory key generation
Browse files Browse the repository at this point in the history
  • Loading branch information
malmeloo committed Feb 7, 2024
1 parent d4a5fce commit 612fe63
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 11 deletions.
26 changes: 18 additions & 8 deletions examples/real_airtag.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,49 @@
This key can be used to retrieve the device's location for a single day.
"""
import plistlib
from datetime import datetime

from findmy import FindMyAccessory

# PUBLIC key that the accessory is broadcasting or has previously broadcast.
# For nearby devices, you can use `device_scanner.py` to find it.
LOOKUP_KEY = "9J5sdEARfh6h0Hr3anfNjy+vnIwETaUodv73ZA=="
PUBLIC_KEY = ""
# Path to a .plist dumped from the Find My app.
PLIST_PATH = "airtag.plist"

# == The variables below are auto-filled from the plist!! ==

with open(PLIST_PATH, "rb") as f:
device_data = plistlib.load(f)

# PRIVATE master key. 28 (?) bytes.
MASTER_KEY = b""
MASTER_KEY = device_data["privateKey"]["key"]["data"][-28:]

# "Primary" shared secret. 32 bytes.
SKN = b""
SKN = device_data["sharedSecret"]["key"]["data"]

# "Secondary" shared secret. 32 bytes.
SKS = b""
SKS = device_data["secondarySharedSecret"]["key"]["data"]

# Lookahead in time slots. Each time slot is 15 minutes.
# Should be AT LEAST the time that has passed since you paired the accessory!
MAX_LOOKAHEAD = 7 * 24 * 4
delta = datetime.now() - device_data["pairingDate"]
MAX_LOOKAHEAD = int(delta.total_seconds() / (15 * 60)) + 1


def main() -> None:
airtag = FindMyAccessory(MASTER_KEY, SKN, SKS)

for i in range(MAX_LOOKAHEAD):
prim_key, sec_key = airtag.keys_at(i)
if LOOKUP_KEY in (prim_key.adv_key_b64, prim_key.adv_key_b64):
if PUBLIC_KEY in (prim_key.adv_key_b64, prim_key.adv_key_b64):
print("KEY FOUND!!")
print(f"This key was found at index {i}."
f" It was likely paired approximately {i * 15} minutes ago")
f" It was likely paired approximately {i * 15} minutes ago.")
print()
print("KEEP THE BELOW KEY SECRET! IT CAN BE USED TO RETRIEVE THE DEVICE'S LOCATION!")
if prim_key.adv_key_b64 == LOOKUP_KEY:
if prim_key.adv_key_b64 == PUBLIC_KEY:
print(f"PRIMARY key: {prim_key.private_key_b64}")
else:
print(f"SECONDARY key: {sec_key.private_key_b64}")
Expand Down
6 changes: 3 additions & 3 deletions findmy/util/crypto.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Pure-python NIST P-224 Elliptic Curve cryptography. Used for some Apple algorithms."""

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.hashes import SHA1
from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF

ECPoint = tuple[float, float]
Expand Down Expand Up @@ -71,7 +71,7 @@
def x963_kdf(value: bytes, si: bytes, length: int) -> bytes:
"""Single pass of X9.63 KDF with SHA1."""
return X963KDF(
algorithm=SHA1(), # noqa: S303
algorithm=hashes.SHA256(),
sharedinfo=si,
length=length,
).derive(value)
Expand All @@ -86,7 +86,7 @@ def derive_ps_key(privkey: bytes, sk: bytes) -> bytes:
"""
Derive a primary or secondary key used by an accessory.
:param pubkey: Public key generated during pairing
:param privkey: Private key generated during pairing
:param sk: Current secret key for this time period.
Use SKN to derive the primary key, SKS for secondary.
"""
Expand Down

0 comments on commit 612fe63

Please sign in to comment.