The user in reddit BobThePigeon_ to writing an excellent research on the work of the PGO +
Within your work we can find the certification process
Current attempts to produce a DIY Pokemon Go Plus have been blocked by a certification process. The device and app will send random data (the "challenge") to each other, and the other side must respond with the correct response in order to certify the app and device as being genuine. Here is what is transacted during the certification (compare with this):
- Device sends 36 bytes: 03000000 + 32 random bytes to SFIDA_TO_CENTRAL, this is a certification challenge; the device is checking that the app is genuine.
- Device sends 4 bytes: 03000000 to SFIDA_COMMANDS, this will notify app
- App sends a response which is 20 bytes: 04000000 + 16 response bytes to CENTRAL_TO_SFIDA.
- Device sends 4 bytes: 04000100 to SFIDA_COMMANDS to notify app that it has received the response.
- App sends 36 bytes: 05000000 + 32 random bytes to CENTRAL_TO_SFIDA, this is a certification challenge; the app is checking that the device is genuine.
- Device sends a response which is 20 bytes: 05000000 + 16 response bytes to SFIDA_TO_CENTRAL.
- Device sends 4 bytes: 05000000 to SFIDA_COMMANDS to notify app that it has responded to the certification challenge.
- App sends 5 bytes: 0300000001 to CENTRAL_TO_SFIDA
- Device sends 4 bytes: 04000200 to SFIDA_COMMANDS
By using a combination of static analysis and debugging, I have determined the algorithm used to generate a certification response from a challenge:
- Split the 32 challenge bytes into two 16 byte halves.
- Encrypt the first 16 byte half using AES-128, using the key bda885742bc53918793ade3fa7b6cf3b.
- Take the encrypted result and XOR it with the second 16 byte half. This gives the response.
Here are some test vectors, obtained from a real device: challenge = 7526c9257080ec4b6366635b0ee5416324673e610d38d7f2440662b272db041f leads to response = 2445be74030f584a7a01fa26490a902e, challenge = 5035fb9119b5bb9de2f4f76803fef5152543b95e02c8791c69fb393215418aa5 leads to response = 78393cb801cd71e17ea977bb1c31acd3.