pentateu / DroidAirPlay

DroidAirPlay is an AirPlay receiver capable of streaming Audio, Video and Photos from iOS devices to an Android 4 device. It's primary use is for in-car systems where Android tables are used as the car dashboard.
GNU General Public License v3.0
193 stars 67 forks source link

fpaeskey vs. rsaaeskey #3

Open robertoandrade opened 10 years ago

robertoandrade commented 10 years ago

From what I could see recently with various challenge exchange in AirPlay, and as noticed on the comment at https://github.com/pentateu/DroidAirPlay/blob/master/src/main/java/nz/co/iswe/android/airplay/audio/RaopAudioHandler.java#L418 the AES Key comes in FairPlay encrypted instead of RSA encrypted and on a different key than it used to be. The code at https://github.com/pentateu/DroidAirPlay/blob/master/src/main/java/nz/co/iswe/android/airplay/audio/RaopAudioHandler.java#L484 only expects parsing the original rsaaeskey but as per the previous comments should also be handling the fpaeskey.

Do you guys have any idea how to go about decrypting that key given it's no longer RSA encrypted? I've seen many documents online about collecting the information sent by the fp-setup phases (as potential dynamic keys) used to decrypt the AES key later on, so rather than simply faking the response as the app does right now, we'd need to interpret those FPLY bytes that come in to be able to store the appropriate information to use when seeding the FP decryption algorithm used to decrypt the AES key late on.

Just thought I'd file this here to start a discussion around it.

pentateu commented 10 years ago

Hi Roberto,

I have not done much on this project for many months, so I'm a bit out of touch with it. But if you are interested in getting it fixed and going I would start work on it again.

I'll have a look at what you said.

Best Regards, Rafael Almeida

On 2/10/2014, at 3:33 am, Roberto Andrade notifications@github.com wrote:

Fro what I could see recently with various challenge exchange in AirPlay, and as noticed on the comment at https://github.com/pentateu/DroidAirPlay/blob/master/src/main/java/nz/co/iswe/android/airplay/audio/RaopAudioHandler.java#L418 the AES Key comes in FairPlay encrypted instead of RSA encrypted and on a different key than it used to be. The code at https://github.com/pentateu/DroidAirPlay/blob/master/src/main/java/nz/co/iswe/android/airplay/audio/RaopAudioHandler.java#L484 only expects parsing the original rsaaeskey but as per the previous comments should also be handling the fpaeskey.

Do you guys have any idea how to go about decrypting that key given it's no longer RSA encrypted? I've seen many documents online about collecting the information sent by the fp-setup phases (as potential dynamic keys) used to decrypt the AES key later on, so rather than simply faking the response as the app does right now, we'd need to interpret those FPLY bytes that come in to be able to store the appropriate information to use when seeding the FP decryption algorithm used to decrypt the AES key late on.

Just thought I'd file this here to start a discussion around it.

— Reply to this email directly or view it on GitHub.

thetrime commented 9 years ago

I can't say for sure, but this is what I concluded as well. The packets involved in the setup are (from what I can tell): 00-03: Magic bytes "FPLY" 04 : Type. 02 for audio, 03 for mirroring, and apparently 0x64 for remote-pairing? 05 : Seems to be 0x1 to establish a session, and 0x2 for an encrypted key 06 : Sequence number 07-10: Unknown. Probably reserved: Appears to always be zeroes? 11 : Length of payload 12+ : Payload.

There are some definite patterns in the setup packets: The first one seems to always be a payload of 0200XXbb (at least on iOS7 it was), and the reply packet always starts 02XX. The third packet begins with XX, and the last packet appears to just be the last 20 bytes of the third packet echoed back. This means that the state is set up in packets 2 and 3, (assuming there is some), since packet 1 contains just 1 byte of information, and packet 4 contains none.

The payload itself is encrypted using FairPlay, and I've got no idea how this works. The fpaeskey parameter that you get with the stream is, as expected, an 'aeskey' encrypted with FairPlay, which is why it's fp-aeskey and not rsa-aeskey. (it's given base64-encoded, too). If you can work out how to decrypt the FairPlay payloads, you can recover the aeskey and then decrypt the stream. I expect this will be very hard without help from Apple in the form of a library (which I expect they will want some money for and an NDA) or by reverse-engineering something (which is probably not legal). Perhaps this information will be of use to someone, though...

robertoandrade commented 9 years ago

Thanks for contributing @thetrime. This is in line with what I had discovered with my research so far. I had posted a question to the Reverse Engineer Stack Exchange to try to get more info on how to go about reverse engineering the code in existing solutions that treat those payloads given there's about a dozen apps out there that I've seen do it (assuming all by reverse engineering Apple's original code which is heavily obfuscated).

robertoandrade commented 9 years ago

04 : Type. 02 for audio, 03 for mirroring, and apparently 0x64 for remote-pairing?

when sending the encrypted key, it seems that type is 01. Did you mean 64 for remote-pairing or 04?