I have a "smart" bulb here that is configured via its vendor application but I would very much prefer if I could use it with my openHAB instance. Using Wireshark, I was able to figure out the following process:
- The bulb opens its own Wifi network
- The android app connects to the bulb Wifi network
- The bulb broadcasts mDNS requests for
_alljoyn._tcp.localto which the app answers with a given TCP port
- The bulb connects to this port and starts AllJoyn communication with an
- Then GUIDs, SessionKeys and GroupKeys are exchanged
configureWificall is made from the app to the bulb which reconnects to the home wifi
- Once they are both reconnected, the app and the bulb start a new set of AllJoyn packets are exchanged, among which there is one with about 400 bytes of encrypted payload and another one with about 7400 bytes also encrypted.
- After that, the bulb and the app both connect to a public Secure MQTT broker to exchange configuration events (on/off, intensity...)
Using a lying DNS server, I was able to get the app to connect to my own secure MQTT broker which gave me the structure of messages sent by the app, but the bulb refuses to connect because it does not know my certificate root CA. This is kinda strange because it is based on Let's Encrypt.
But looking at the result of
openssl s_client -showcerts -connect originalmqtt.manufacturer.com:8883 on the original MQTT broker, I see that it uses a certificate whose root CA is a custom generated one. Sadly, it is not broadcast by the broker itself. But I believe that it is present in those 7400 encrypted bytes above.
Looking more closely at the timing of packets, I could figure that before those 7400 bytes are sent, there is first a HTTPs request made by the app to a manufacturer webservice which returns a large answer as well.
I thus setup an instance of
mitmproxy in transparent mode with the help of
iptables and I could thus see what's going in those HTTPs requests.
Clearly, there is a JWT sent to the web service, which replies with another JWT, but this reply is encrypted as well. Yes, encrypted then sent over HTTPs that adds a second layer of encryption.
This means, that either I can decrypt the JWT payload or I can decrypt the AllJoyn data packets.
As the former seems more complicated, I focused my attention to the latter and after reading this page, I went looking for data files on the android device that hosts the app.
I found a file named
alljoyn_keystore that is 26 bytes long and whose content changes everytime I redo the whole pairing procedure above. I thus believe it does contain the secret key used for AllJoyn communication but its length is weird as the documentation says the master key is 48 bytes in length as per RFC 5246.
After this detailed explanation, I'm left with those questions:
- Is this the right place to discuss this. If not, where would you recommend I ask my question?
- Do you think it would be possible to decrypt those packets? Would you have any resources that I should look at?
Thanks for any suggestion