librespot-org / librespot-java

The most up-to-date open source Spotify client
Apache License 2.0
382 stars 94 forks source link

Changing platform value causing errors during key exchange #662

Open florisvoskamp opened 1 year ago

florisvoskamp commented 1 year ago

Describe the bug

The bug may not necessarily be a bug; it could be considered a feature request and/or bug report combined. I have conducted tests using my own premium account.

When using the following platform values during the client hello of the key exchange, an error of 'try another AP' occurs:

Similarly, when using the following platform values during the client hello of the key exchange, an error of 'premium required' occurs:

To Reproduce Modify the platform() function in Version.java as follows:

public static Platform platform() {
    return Platform.PLATFORM_ANDROID_ARM; // or any other value from the list that causes issues
}

Expected behavior I expected the program to continue functioning correctly, as the appropriate platform variables should work. It is important to accurately identify the device from Spotify's side, so I want to ensure that this identification remains as accurate as possible.

SuisChan commented 1 year ago

In some cases (as described by you above) the server expects the correct set of device info during the key-exchange, so changing the PLATFORM alone may not be enough.

As far as I remember, when targeting mobile devices, at least PRODUCT_MOBILE must be set, as well as the right data provided when sending ClientResponseEncrypted message.

Therefore, I consider this not a bug, but a feature of the server when working with the client.

florisvoskamp commented 1 year ago

You are correct. That is indeed a feaure. I must say it is my fault for not being clear enough in my original message.

Even with this in check, it still does not work:

Maybe there are less obvious values that need to be changes for this to work correctly that I am missing? I cannot get it to work even if I set all of the above values correctly with each other.

SuisChan commented 1 year ago

Maybe there are less obvious values that need to be changes

I don’t know how it is now, but before, with these fields filled in, everything worked fine

ClientHelloMsg ```json "ClientHello": { "buildInfo": { "product": "PRODUCT_MOBILE", "productFlags": [ "PRODUCT_FLAG_NONE" ], "platfrom": "PLATFORM_ANDROID_ARM", "version": "....." }, "fingerprintsSupported": [ "FINGERPRINT_GRAIN" ], "cryptosuitesSupported": [ "CRYPTO_SUITE_SHANNON" ], "powschemesSupported": [ "POW_HASH_CASH" ], "loginCryptoHello": { "diffieHellman": { "gc": "......................", "serverKeysKnown": 1 } }, "clientNonce": "...............", "padding": "...........", "featureSet": { "autoupdate2": true, "unknown_3": {}, "unknown_5": { "unknown_1": 0 } } } ```
ClientResponseEncryptedMsg ```json "ClientResponseEncrypted" { "login_credentials" { "username": "................." "type": "AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS" "auth_data": "...................." } "account_creation": "ACCOUNT_CREATION_ALWAYS_PROMPT" "fingerprint_response" { "grain" { "encrypted_key": "................" } } "system_info" { "cpu_family": "CPU_ARM" "cpu_subtype": 0 "cpu_ext": 0 "brand": "BRAND_UNBRANDED" "brand_flags": 0 "os": "OS_ANDROID" "os_version": 0 "os_ext": 0 "system_information_string": "................." "device_id": ".............." } "platform_model": "..............." "version_string": "......" "client_info" { "limited": false "language": "....." }, ```
florisvoskamp commented 1 year ago

I don’t know how it is now, but before, with these fields filled in, everything worked fine

ClientHelloMsg ClientResponseEncryptedMsg

Do you know what these values would need to be set to:

Also, I notice the APWelcome also contains a fingerprint challenge? How do I solve this so I can send the encrypted_key for the fingerprint_response?

I have tried with all of these values set, including the ones mentioned above, however the encrypted_key for example is currently still an empty string bytes. I have managed to make the APWelcome work, however the the response after the ClientResponsePlainText is always bad credentials.

SuisChan commented 1 year ago

Do you know what these values would need to be set to:

  • version under buildInfo
  • system_information_string under system_info
  • platform_model
  • version_string

Also, I notice the APWelcome also contains a fingerprint challenge? How do I solve this so I can send the encrypted_key for the fingerprint_response?

First of all, sorry for the late reply

I can’t provide exact data at the moment, but what I remember is this:

As for the Fingerprint challenge, I can explain what and how it works, but not now, I need to find time for this, but key-exchange should definitely work without it, as well as without pow_scheme (hashcash)

florisvoskamp commented 1 year ago

Do you know what these values would need to be set to:

  • version under buildInfo
  • system_information_string under system_info
  • platform_model
  • version_string

Also, I notice the APWelcome also contains a fingerprint challenge? How do I solve this so I can send the encrypted_key for the fingerprint_response?

First of all, sorry for the late reply

I can’t provide exact data at the moment, but what I remember is this:

  • BuildInfo/version is the application version itself, for example - 88360522
  • system_information_string - brief information about the device, apparently taken from build.prop (like API version, device name and platform arm/x86) (if we talk about mobile devices)
  • platform_model - really don't remember what's there
  • version_string - the same version as in the first field, but provided as a string, for example - "8.8.3.6.522"

As for the Fingerprint challenge, I can explain what and how it works, but not now, I need to find time for this, but key-exchange should definitely work without it, as well as without pow_scheme (hashcash)

Thank you for the reply, you have been most helpful. I will try without the valid fingerprint challenge shortly, and double check if the key exchange still does not work.

Let me know when you would be able to further explain the fingerprint challenge and how to solve it. There is absolutely no rush, so take your time.

SuisChan commented 1 year ago

Let me know when you would be able to further explain the fingerprint challenge and how to solve it. There is absolutely no rush, so take your time.

Sorry for taking so long, I created an example with code (Rust), it should explain how it works (well, I hope ))

For an example it will use ready-made data, as it's allow to show the very essence and how it works, since if something is wrong - the server will not throw any error, so it makes sense to show everything with pre-generated data. (data actually received from the application runtime, therefore correct)

If you have any questions feel free to ask, there is also a Gitter chat that can be helpful too