custom-components / ble_monitor

BLE monitor for passive BLE sensors
https://community.home-assistant.io/t/passive-ble-monitor-integration/
MIT License
1.89k stars 243 forks source link

Find out BLE Key on iOS #198

Closed nenadmilano closed 3 years ago

nenadmilano commented 3 years ago

Unfortunately I got sent some CCGQ02HL (Xiaomi Mijia Window Door Sensor 2) instead of the Zigbee Version and now I am facing the issue to integrate them into Home Assistant. I found your repo and custom integration but i struggle to find out the BLE encryption key for the sensors. I don’t have an android phone at hand, just iOS devices. In the Readme you mention to open up an issue to figure out a new way to get the key so I would kindly ask for your support.

Thanks!

Magalex2x14 commented 3 years ago

Yes, I promised, but for now I have to postpone it - I have a very busy time now. I’m afraid I’ll only be able to walk the path of getting the key with you step by step next year, it seems ... Do you have any way to get an android device for a while?

I can only tell you briefly how I did it on iOS:

image

image

from base64 import b64decode, b64encode
import hashlib

def rc4mi(ddata, dkey):
    s, j, out = list(range(256)), 0, []

    for i in range(256):
        j = (j + ord(dkey[i % len(dkey)]) + s[i]) % 256
        s[i], s[j] = s[j], s[i]

    # 1024 fake rounds
    i = j = 0
    for _ in range(1024):
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]

    for ch in ddata:
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        out.append(chr(ord(ch) ^ s[(s[i] + s[j]) % 256]))

    return "".join(out)

if __name__ == "__main__":

    #
    # Fill SSEC, NONCE, DATA
    #

    SSEC = "KzfNrjkjsdgfjkCOiqpWw=="
    NONCE = "UJDMREGHTRTEu"
    DATA = "Gzc4ERTGRETGERTGRETGREGTerttgretgertgerGRTEGERTGERTGERTEGERTggerrtgertg+vJcKw=="

    key = b64encode(hashlib.sha256(b64decode(SSEC) + b64decode(NONCE)).digest())

    print("CLEARTEXT: {}".format(rc4mi(b64decode(DATA), b64decode(key))))

As a result of executing this program, you will see the decrypted text containing the key bind_key:

image

Magalex2x14 commented 3 years ago

@Ernst79, Can I ask you to include a link to this to the FAQ for a while until we have better instructions?

Ernst79 commented 3 years ago

Yes, will do.

Ernst79 commented 3 years ago

Link is added to FAQ

huangyafei commented 3 years ago
WX20201224-005020@2x

I don't know why this is happening, it's so weird.

declanjscott commented 3 years ago

Hi @nenadmilano

If you're still stuck, I was able to obtain the key on Chrome on my Mac by activating using the Telink Flasher: http://atc1441.github.io/TelinkFlasher.html

Ernst79 commented 3 years ago

I think that only works for LYWSD03MMC, not for CCGQ02HL.

declanjscott commented 3 years ago

Whoops sorry about that - I misread!

Hyoengju-Johannes-Lee commented 3 years ago
WX20201224-005020@2x

I don't know why this is happening, it's so weird.

I had the same issue, and I noticed that the character "+" is written as %2B, and "=" as %3D. If your "data" contains %?? (? would be a number or a letter), find the letter from this link, (https://www.w3schools.com/tags/ref_urlencode.ASP) and change the %?? to the corresponding character.

gpoul commented 3 years ago

Just to add here as it might be useful for someone who finds this or for me later in life ;-)

I used mitmproxy on a raspberry and an Android phone:

sudo apt-get install mitmproxy
mitmproxy -p 1234

For me then the rendering in the browser didn't allow the download & install of the cert; so this needed to be fixed as follows:

wget https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css
sudo mkdir -p /usr/lib/python3/dist-packages/mitmproxy/addons/onboardingapp/static/fontawesome/css
sudo mv all.min.css /usr/lib/python3/dist-packages/mitmproxy/addons/onboardingapp/static/fontawesome/css/font-awesome.min.css

The font will not work, but at least we can now install the cert.

I have not used the original app, but the mod that creates the pairings.txt recommended in #7 and then used the python script above to decode the data from the /bltbind request. Both of the things successfully extracted the same bind key.

truethe1mc commented 3 years ago
WX20201224-005020@2x

I don't know why this is happening, it's so weird.

I had the same issue, and I noticed that the character "+" is written as %2B, and "=" as %3D. If your "data" contains %?? (? would be a number or a letter), find the letter from this link, (https://www.w3schools.com/tags/ref_urlencode.ASP) and change the %?? to the corresponding character.

hello everyone, first of all, thanks for all the contribution done so far, i was able to move a little forward with CGDK2 sensor bind key obtaining. However, i have the same issue, no %2B or %3D or %?? in data filed as it was decoded, but non readable characters as an output.. Probably the script doesn't work anymore?

CLEARTEXT: ˑ▒ ▒Tު7u6▒/▒i▒▒{▒▒4▒▒▒ۆ ▒[▒V▒▒▒▒▒▒▒▒▒t▒ŗ▒5\▒J[|▒▒▒▒ŝ▒▒▒▒X7▒▒3▒#fu+▒r+▒`▒H▒▒▒/▒#▒▒ˠNig▒~ 6y▒ٲ▒▒▒>ȒX▒`▒▒oo)Rt▒▒▒)

truethe1mc commented 3 years ago

CLEARTEXT: ˑ▒ ▒Tު7u6▒/▒i▒▒{▒▒4▒▒▒ۆ ▒[▒V▒▒▒▒▒▒▒▒▒t▒ŗ▒5\▒J[|▒▒▒▒ŝ▒▒▒▒X7▒▒3▒#fu+▒r+▒▒H▒▒▒/▒#▒▒ˠNig▒~ 6y▒ٲ▒▒▒>ȒX▒▒▒oo)Rt▒▒▒)

Was able to solve this, Sequence is important as well as the timing. Previously took the data from different sniffing sessions while now did firstly MiHome relogin, then adding new devices. Works well.

zaygraveyard commented 3 years ago

Hello everyone, first of all, thanks for all the amazing contributions done so far

I created a small repl.it program that takes the ssecurity, _none and data fields and spits out the bind_key

It's based on @Magalex2x14's script (see https://github.com/custom-components/ble_monitor/issues/198#issuecomment-748638122), updated to Python 3 and to handle decoding the %?? in the fields as well as spits out the bind_key automatically

I hope this helps

PS: I used Stream app in iOS (the low quality of the Chinese alternative @Magalex2x14 mentioned) and it works amazingly well (you should just remember to disable the Stream certificate when done sniffing :wink:)

Ernst79 commented 3 years ago

It now seems that method 2 in the faq is working on iOS. Note that the webBLE app is a paid app and I haven’t tried it myself.