Skip to content

Pyicloud SRP i code #381

Description

@gcobb321

@Ghawken @iowk
I’ve created a new issue away from the iCloud3 users posting their status.

I’m having a problem integrating the new authorize_with_password code into iCloud3 running under Home Assistant. I can get @iowk’s code running stand alone but keep running into a problem on the first init transaction to https://idmsa.apple.com/appleauth/auth/signin/init. The response is empty so there is no data/body[ ‘salt’] value to use later on. I have verified that the url, data and header values are the same except for a, the session_id, and token values between the HA and standalone program running under vscode.

The result in getting is

POST TO APPLE …….
 method='POST' url='https://idmsa.apple.com/appleauth/auth/signin/init'  
 kwargs={'data': {'a': 'RzPCL16IOLdwfJ89oCi8R8kEVj7O1bWdoAg7bJYtwKMo0IWm1YELR9RT0a+PwML3omzZk8c6MnQujYUsaYXQaH+oV7vR1jr58K3yTratxPhJ+kPuDDNOEsol0cPTvSRNdqNcXds7cNjHe22sDkUDHNoYCUcTxATRWAGEHyKbhvS4l3MRebgUxySwudUSmb+5Q3t2lgw7cB5LbORTi27SlOnexuzzk0jURUsqxPjQ+4SRFNoIXLqrrC2TK22iUTHWTmk204JBYggF3dsfQ1qhcCuC2JG6flnlT+Jcjr9gmMDUNRzkbl2pu7tH9yAKfORFLLQhSpA/QRw3+lZUS+Tf3w==', 'accountName': 'xxxxxx@xxxxxxx', 'protocols': ['s2k', 's2k_fo']}, 'json': None, 'headers': {'Accept': 'application/json, text/javascript', 'Content-Type': 'application/json', 'X-Apple-OAuth-Client-Id': 'd39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d', 'X-Apple-OAuth-Client-Type': 'firstPartyAuth', 'X-Apple-OAuth-Redirect-URI': 'https://www.icloud.com', 'X-Apple-OAuth-Require-Grant-Code': 'true', 'X-Apple-OAuth-Response-Mode': 'web_message', 'X-Apple-OAuth-Response-Type': 'code', 'X-Apple-OAuth-State': 'auth-5961e7e4-90c4-11ef-9028-2ccf674e40a8', 'X-Apple-Widget-Key': 'd39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d'}} 

RESPONSE…..
 data={} response.status_code=400  (SOMETIMES THIS IS 503)

10-23 02:40:39 iCloud3 v3.1b11
Traceback (most recent call last):
  File "/config/custom_components/icloud3/support/pyicloud_ic3_interface.py", line 136, in log_into_apple_account
    PyiCloud = PyiCloudService( username, password,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/icloud3/support/pyicloud_ic3.py", line 811, in __init__
    self.authenticate()
  File "/config/custom_components/icloud3/support/pyicloud_ic3.py", line 938, in authenticate
    if self._authenticate_with_password_srp():
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/icloud3/support/pyicloud_ic3.py", line 1150, in _authenticate_with_password_srp
    salt = base64.b64decode(data['salt'])
                            ~~~~^^^^^^^^
KeyError: 'salt

My code:


        headers = self._get_auth_headers()
        if self.session_data.get("scnt"):
            headers["scnt"] = self.session_data.get("scnt")
        # if self.session_data.get("session_id"):
        #     headers["X-Apple-ID-Session-Id"] = self.session_data.get("session_id")
        if self.session_id:
            headers["X-Apple-ID-Session-Id"] = self.session_id

        class SrpPassword():
            def __init__(self, password: str):
                self.password = password

            def set_encrypt_info(self, salt: bytes, iterations: int, key_length: int):
                self.salt = salt
                self.iterations = iterations
                self.key_length = key_length

            def encode(self):
                _log(f"SRP111PW {str(self.password)=}")
                password_hash = hashlib.sha256(self.password.encode('utf-8')).digest()
                return hashlib.pbkdf2_hmac('sha256', password_hash, salt, iterations, key_length)

        srp_password = SrpPassword(self.password)
        srp.rfc5054_enable()
        srp.no_username_in_x()
        usr = srp.User(self.username, srp_password, hash_alg=srp.SHA256, ng_type=srp.NG_2048)

        srp_username, A = usr.start_authentication()
        _log(f"{self.username=} {self.password=} {srp_username=} {A=}")

        self.AUTH_ENDPOINT = "https://idmsa.apple.com/appleauth/auth"
        url  = f"{self.AUTH_ENDPOINT}/signin/init"
        data = {
            'a': base64.b64encode(A).decode(),
            'accountName': srp_username,
            'protocols': ['s2k', 's2k_fo']
        }

        try:
            _log(f"SRP-948 {url=} {data=}")
            response = self.PyiCloudSession.post(url, data=data, headers=headers)
            # response.raise_for_status()

SRP is not in the standard HA library so I have had to add it to a HA manifest.json file as a requirement which gets processed at load time to add it to the site-library. I do not know what version is loaded. I’m running on a Raspberry Pi with their own OS.

Any thoughs would be appreciated on where to look or what might be wrong.

  • different SRP, hashtag, base64 encode/decode versions between HA and vscode
  • a is not getting seeded properly

I’m running Python 3.13,

Thanks

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions