mog

shitchosting wizard

jack of all trades, master of some
hungarian


i am personally responsible for the following horrible things here:

choost

windows xp takeover

cohost place

warioware

cohost DOOM

what is cohost listening to?

memomaze

cohost bbs


last.fm listening


🏠 personal site
mogery.me/
mastodon
@mogery@social.treehouse.systems

UNFINISHED, might write a talk on this

This is a long and rambly post about Spotify's previous protocol, implemented by the old libspotify. Why not talk about the current one? Well, the old one is much, MUCH more unhinged, and frankly, it makes for a better post. And, even though it was discontinued in 2022, it still seems to be working, and doesn't require any shitty DRM tech.


AP Discovery & Handshake

To start communicating, you first need to find a Spotify AP (access point). To get a list of available APs, you need to make a GET request to apresolve.spotify.com. You'll get something like this back:

{"ap_list":["ap-gew1.spotify.com:4070","ap-gew1.spotify.com:443","ap-gew1.spotify.com:80","ap-gew1.spotify.com:4070","ap-gae2.spotify.com:443","ap-gue1.spotify.com:80"]}

You could pick any one of these, but picking the first one will probably get you the best results.

The 1st API sin committed by Spotify here is that even though ports 80 and 443 are used, these are not HTTP nor HTTPS connections. It's actually protobuf over TCP, prefixed with the packet length. The very first packet (sent by the client) is also prefixed with a two-byte header, hardcoded to 00 04.

Once you've connected, since this is not over TLS or anything, the connection is initially insecure. Here's what libspotify does to create a secure, encrypted tunnel:

  1. Send a client hello with cryptographic and runtime metadata.
  2. Receive a server hello with a cryptographic challenge.
  3. Concatenate these two packets and put them into an accumulator buffer.
  4. Perform a Diffie-Hellman key exchange to establish a shared key.
  5. Perform HMAC-SHA1 6 times on the accumulator and the number of the iteration with the shared key, and concatenate the 6 MACs into a new MAC buffer.
  6. Perform HMAC-SHA1 on the accumulator using the 1st MAC in the MAC buffer as the key. This new MAC becomes the answer to the server's challenge.
  7. Respond to the server with the challenge.
  8. Initialize 2 instances of the Shannon stream cipher, one for encoding and one for decoding, using different parts of the MAC buffer as keys.

The Shannon stream cipher was designed by Greg Rose sometime in the 2000s at QUALCOMM Australia. The reference code (linked above) or even a description of it is extremely hard to hunt down, which makes this a part of the biggest sin committed here: security through obscurity.

A stream cipher, in contrast to block cipher, encrypts data continuously, so instead of needing to bundle up your data in x-byte blocks in order to deliver them securely, you can just yell 1s and 0s down a tube and everything will be fine. Anyways, Shannon is a pretty good stream cipher, designed originally for telephony, but applicable basically anywhere. From a security standpoint, while it may be a bit undertested, it's an OK choice for this.

One more weird thing is that the protocol supports a second, newer key exchange method, using RC4 and HMAC with SHA1, which is very questionable, since, while SHA1 was only declared dead semi-recently, RC4 was broken since 5 years before Spotify was founded.


You must log in to comment.