Coder Social home page Coder Social logo

mihome-binary-protocol's Introduction

Xiaomi's MiHome Binary protocol

Summary

Xiaomi is a manufacturer of smart home devices under the "MiHome" label. These devices use an encrypted, proprietary network protocol to communicate with the official smartphone app. It operates on UDP port 54321.

This repository documents the protocol, henceforth referred to as "mihobi", and contains exemplary source code to parse and analyze.

The main goal is to remove the dependence on proprietary software, and to regain control over your own devices.

It has been developed with the Yeelight RGBW smart bulb. Other devices might use yet unimplemented features.

Yeelight bulb

Documents

doc/PROTOCOL.md

Tools

pcap-decrypt.py

Recovers the protocol from pcap-ng dumps and attempts to decrypt the packet payloads.

Dependencies:

  • Python 3.5+
  • tshark, the command-line version of Wireshark
  • PyShark, a Python wrapper for tshark
  • cryptography, a Python library which exposes cryptographic recipes and primitives.

Installation:

apt-get install tshark
pip3 install pyshark
pip3 install cryptography

Usage:

./pcap-decrypt.py capture.pcapng.gz

Example output:

### 192.168.13.2 => 192.168.13.1 (xx:xx:xx:xx:xx:xx => yy:yy:yy:yy:yy:yy)
META: Hello

### 192.168.13.1 => 192.168.13.2 (yy:yy:yy:yy:yy:yy => xx:xx:xx:xx:xx:xx)
META: device yy:yy:yy:yy:yy:yy has token: abcdef1234567890abcdef1234567890

### 192.168.13.2 => 192.168.13.1 (xx:xx:xx:xx:xx:xx => yy:yy:yy:yy:yy:yy)
{"id":1234567890,"method":"miIO.config_router",
"params":{"ssid":"WiFi name","passwd":"WiFi password","uid":987654321}}

### 192.168.13.1 => 192.168.13.2 (yy:yy:yy:yy:yy:yy => xx:xx:xx:xx:xx:xx)
{"result":["ok"],"id":1234567890}

miio.py

Core Python library that parses and generates MiHoBi packets.

Notes

As of 2017-02-10, the initialization process ("SmartConnect") leaks the user's WiFi credentials, due to weak encryption. See PROTOCOL.md for more details. I do not recommended connecting MiHome devices to your main WiFi network.

Appendix

Legal

Xiaomi is a registered trademark and service mark of Xiaomi Inc., which is not affiliated with the maker of this program and does not endorse, service or warrant the functionality of this product.

Author

The source code and documention in this repository

(c) 2016-2017 Wolfgang Frisch

Licensed under the GPLv3.

mihome-binary-protocol's People

Contributors

wfr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mihome-binary-protocol's Issues

Errors in the miio.py and protocol docs

I tried recreating (in my own Python 2 code) a mihome packet that I sniffed with the protocol docs but I wasn't able to get the MD5 checksum right. The protocol docs say this value should be initialized with zeroes. However, in the miio.py code this field is initialized to the device token value. The init_msg_head function also has an error where it uses an "unknown const" value which should be the Device ID (did) value. When I used my own Device ID with the device token in the md5 checksum field before the MD5 calculation I got the correct packet.

Extracting the device token from the Yeelight app

Great project! Exactly what I was looking for. I have a Yeelight RGBW with an updated firmware and noticed that indeed the token in the "Hello" packet is missing. I did manage to extract the device token from the Yeelight Android app and was then able to decrypt the packets.

To extract the token you need to access the app's private files. If your phone is rooted you can just find the file miot.xml with a root file explorer in the app's private directory. If your phone is not rooted you need to backup the app's files using adb like so:
adb backup '-noapk com.yeelight.cherry' -f /your/local/path/yeelight.ab

The .ab file is pretty well documented and there are many extractors for it. I personally used this simple python method:
http://stackoverflow.com/questions/29055634/python-unpack-android-backup

After extracting the tar file open the following XML file:
./apps/com.yeelight.cherry/sp/miot.xml

This XML file contains a set element called deviceList and inside it you will find an HTML escaped JSON string for your device. This JSON contains a token value with your device token encoded as a simple 16 byte hexadecimal string. You can use this token to decrypt the MiHome binary protocol packets sent from the phone to the Xiaomi device.

This file may also be useful for decrypting the Xiaomi cloud protocol since it contains some interesting values about the Xiaomi user like mMacAlgorithm and mMacKey.

Incorrect formula for IV

In PROTOCOL.md, the formula for initialization vector is
IV = MD5(MD5(Key) + Token)
However, the following apears to be correct instead (at least for my dreame.vacuum.mb1808):
IV = MD5(Key + Token)

Device <=> Cloud communication

The documentation and proof-of-concept code only cover communication between the device and the user's phone.

However the device also uses a very similar protocol to talk to Xiaomi's servers.
It's most likely the same protocol, just with a different encryption key.

Phone <=> Cloud communication

The phone app uses a very different protocol to talk to Xiaomi's servers.
It operates on HTTP with RC4 based encryption.

Question on the "Hello packet"

I am reading into the topic with the hope to be able to speak to my Roborock vacuum cleaner using UDP messages in an enclosed WiFi without connection to the world wide web (to avoid communication between the robot and any foreign server):

I do not yet understand, when this "Hello packet" is send: my robot is not connected to any WiFi. I can put some keys and then it is waiting for input from the App: does the App connect to the robot via a direct WiFi connection and then speaks to it via UDP?
Does anyone know a source for further reading on this processes?

Any help is very welcome. Thank you and best regards

./pcap-decrypt.py capture.pcapng.gz error

Traceback (most recent call last):
  File "./pcap-decrypt.py", line 67, in <module>
    args.pcapfile, display_filter=("udp.port == 54321"))
  File "/usr/local/lib/python3.5/dist-packages/pyshark/capture/file_capture.py", line 47, in __init__
    raise FileNotFoundError(str(self.input_filename))
FileNotFoundError: capture.pcapng.gz

Hello,
Need help with above error

Is the token use changing?

Hi,

A few weeks ago I decided to write my own library to control Yeelights using the protocol described here. I wanted to have provisioning and token harvesting (library aioiotprov) and control (aioyeelight)

So I took one of my Yeelight and started developing. .. I went well, soon I got provisioning and token harvesting working... and a bit later I got full control over the bulbs, including 'music_mode'

I published my work.
There was much rejoicing.

But then I decided to move over some of my others Yeelight... And I suddenly hit this peculiar problem..... Provisioning always works, but the harvested token result in an MD5 field filled with 0xff

I did reset my initial bulb, and went to the process again... Works good

I provisioned a Xiaomi HS2 air purifier... Provisioning works, token not.

Now my others Yeelights were using the so-called "LAN protocol" and I got them updated to the latest firmware. I wonder...

To make sure it was not just my library, I used python-miio and it behaves exactly the same way as aioyeelight.

There is one peculiar thing I did notice. After sending the hello packet, the response to the next command as the md5 field full of 0xff, but the packet size is much bigger than it should.

Has anyone encountered something like this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.