From b9da67825e2bb26884963c878c6cd143e3445db2 Mon Sep 17 00:00:00 2001 From: Andrey Nikiforov Date: Tue, 3 Dec 2024 08:20:47 -0800 Subject: [PATCH] add s2k_fo srp protocol support #975 (#1014) --- CHANGELOG.md | 1 + src/pyicloud_ipd/base.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfac079d1..9d17e8dfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- fix: failed to authenticate for accounts with srp s2k_fo auth protocol [#975](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/975) - fix: failed to login non-2FA account for the first attempt [#1012](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/1012) - fix: log more information for authentication error [#1010](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/1010) - feature: add support for XMP files with `--xmp-sidecar` parameter [#448](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/448), [#102](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/102), [#789](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/789) diff --git a/src/pyicloud_ipd/base.py b/src/pyicloud_ipd/base.py index f429291d7..a0d16ed51 100644 --- a/src/pyicloud_ipd/base.py +++ b/src/pyicloud_ipd/base.py @@ -200,19 +200,22 @@ class SrpPassword(): def __init__(self, password: str): self.pwd = password - def set_encrypt_info(self, salt: bytes, iterations: int) -> None: + def set_encrypt_info(self, protocol: str, salt: bytes, iterations: int) -> None: + self.protocol = protocol self.salt = salt self.iterations = iterations def encode(self) -> bytes: + password_hash = hashlib.sha256(self.pwd.encode()) + password_digest = password_hash.hexdigest().encode() if self.protocol == 's2k_fo' else password_hash.digest() key_length = 32 - return hashlib.pbkdf2_hmac('sha256', hashlib.sha256(self.pwd.encode()).digest(), self.salt, self.iterations, key_length) + return hashlib.pbkdf2_hmac('sha256', password_digest, salt, iterations, key_length) # Step 1: client generates private key a (stored in srp.User) and public key A, sends to server srp_password = SrpPassword(self.user["password"]) srp.rfc5054_enable() srp.no_username_in_x() - usr = srp.User(self.user["accountName"], srp_password, hash_alg=srp.SHA256) + usr = srp.User(self.user["accountName"], srp_password, hash_alg=srp.SHA256, ng_type=srp.NG_2048) uname, A = usr.start_authentication() data = { 'a': base64.b64encode(A).decode(), @@ -234,9 +237,10 @@ def encode(self) -> bytes: b = base64.b64decode(body['b']) c = body['c'] iterations = body['iteration'] + protocol = body['protocol'] # Step 3: client generates session key M1 and M2 with salt and b, sends to server - srp_password.set_encrypt_info(salt, iterations) + srp_password.set_encrypt_info(protocol, salt, iterations) m1 = usr.process_challenge( salt, b ) m2 = usr.H_AMK