Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find out BLE Key on iOS #198

Closed
nenadmilano opened this issue Dec 15, 2020 · 14 comments
Closed

Find out BLE Key on iOS #198

nenadmilano opened this issue Dec 15, 2020 · 14 comments
Labels
documentation Improvements or additions to documentation

Comments

@nenadmilano
Copy link

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
Copy link
Collaborator

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:

  • firstly, I decided to purchase the Charles proxy app (due to the low quality of the Chinese alternative and the availability of the desktop version of Charles, with which it is more convenient to dig into the traffic recorded on the phone)

  • to decrypt a request containing bind_key, it is necessary to intercept the ssecurity key, for me, this key appears in traffic only when a user is authorized in MiHome, that is, I had to log out of my account and log in with Charles proxy enabled. Save your ssecurity key in a safe place in case you need it again. This is what the request looked like:

image

  • then you need to intercept the request when adding a device to MiHome (as it was before). From this request, you will need the nonce and data fields. This is how the request looks now:

image

  • you need to insert the data obtained in the previous paragraphs into the following Python program and execute it. In Python 3, it did not work for me, I did not bother with this, and ran it with Python 2:
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
Copy link
Collaborator

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

@Ernst79
Copy link
Collaborator

Ernst79 commented Dec 20, 2020

Yes, will do.

@Ernst79
Copy link
Collaborator

Ernst79 commented Dec 22, 2020

Link is added to FAQ

@huangyafei
Copy link

WX20201224-005020@2x

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

@declanjscott
Copy link

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
Copy link
Collaborator

Ernst79 commented Dec 29, 2020

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

@declanjscott
Copy link

Whoops sorry about that - I misread!

@Hyoengju-Johannes-Lee
Copy link

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
Copy link

gpoul commented Jan 18, 2021

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
Copy link

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
Copy link

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.

@Ernst79 Ernst79 added the documentation Improvements or additions to documentation label Feb 23, 2021
@zaygraveyard
Copy link

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 #198 (comment)), 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 😉)

@Ernst79
Copy link
Collaborator

Ernst79 commented Jul 20, 2021

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.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

9 participants