mirror of
https://github.com/malmeloo/FindMy.py.git
synced 2026-04-17 22:53:56 +02:00
Fix accessory key generation
This commit is contained in:
@@ -4,25 +4,35 @@ Example showing how to retrieve the primary key of your own AirTag, or any other
|
|||||||
|
|
||||||
This key can be used to retrieve the device's location for a single day.
|
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
|
from findmy import FindMyAccessory
|
||||||
|
|
||||||
# PUBLIC key that the accessory is broadcasting or has previously broadcast.
|
# PUBLIC key that the accessory is broadcasting or has previously broadcast.
|
||||||
# For nearby devices, you can use `device_scanner.py` to find it.
|
# 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.
|
# PRIVATE master key. 28 (?) bytes.
|
||||||
MASTER_KEY = b""
|
MASTER_KEY = device_data["privateKey"]["key"]["data"][-28:]
|
||||||
|
|
||||||
# "Primary" shared secret. 32 bytes.
|
# "Primary" shared secret. 32 bytes.
|
||||||
SKN = b""
|
SKN = device_data["sharedSecret"]["key"]["data"]
|
||||||
|
|
||||||
# "Secondary" shared secret. 32 bytes.
|
# "Secondary" shared secret. 32 bytes.
|
||||||
SKS = b""
|
SKS = device_data["secondarySharedSecret"]["key"]["data"]
|
||||||
|
|
||||||
# Lookahead in time slots. Each time slot is 15 minutes.
|
# Lookahead in time slots. Each time slot is 15 minutes.
|
||||||
# Should be AT LEAST the time that has passed since you paired the accessory!
|
# 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:
|
def main() -> None:
|
||||||
@@ -30,13 +40,13 @@ def main() -> None:
|
|||||||
|
|
||||||
for i in range(MAX_LOOKAHEAD):
|
for i in range(MAX_LOOKAHEAD):
|
||||||
prim_key, sec_key = airtag.keys_at(i)
|
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("KEY FOUND!!")
|
||||||
print(f"This key was found at index {i}."
|
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()
|
||||||
print("KEEP THE BELOW KEY SECRET! IT CAN BE USED TO RETRIEVE THE DEVICE'S LOCATION!")
|
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}")
|
print(f"PRIMARY key: {prim_key.private_key_b64}")
|
||||||
else:
|
else:
|
||||||
print(f"SECONDARY key: {sec_key.private_key_b64}")
|
print(f"SECONDARY key: {sec_key.private_key_b64}")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""Pure-python NIST P-224 Elliptic Curve cryptography. Used for some Apple algorithms."""
|
"""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.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives.hashes import SHA1
|
|
||||||
from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF
|
from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF
|
||||||
|
|
||||||
ECPoint = tuple[float, float]
|
ECPoint = tuple[float, float]
|
||||||
@@ -71,7 +71,7 @@ P224_P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001
|
|||||||
def x963_kdf(value: bytes, si: bytes, length: int) -> bytes:
|
def x963_kdf(value: bytes, si: bytes, length: int) -> bytes:
|
||||||
"""Single pass of X9.63 KDF with SHA1."""
|
"""Single pass of X9.63 KDF with SHA1."""
|
||||||
return X963KDF(
|
return X963KDF(
|
||||||
algorithm=SHA1(), # noqa: S303
|
algorithm=hashes.SHA256(),
|
||||||
sharedinfo=si,
|
sharedinfo=si,
|
||||||
length=length,
|
length=length,
|
||||||
).derive(value)
|
).derive(value)
|
||||||
@@ -86,7 +86,7 @@ def derive_ps_key(privkey: bytes, sk: bytes) -> bytes:
|
|||||||
"""
|
"""
|
||||||
Derive a primary or secondary key used by an accessory.
|
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.
|
:param sk: Current secret key for this time period.
|
||||||
Use SKN to derive the primary key, SKS for secondary.
|
Use SKN to derive the primary key, SKS for secondary.
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user