Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upGeneral Discussion #5
Comments
|
Yep. To find the prefix and suffix for new devices, you'll have to fire up Wireshark and sniff the packets going to your device. The data portion of the packet starts with a version number (probably 3.1) and ends with I'm guessing this padding has an actual meaning, but so far I haven't been able to find anything. @blackrozes has suggested that it's just random data with a few special bytes in the beginning and end as devices seem to expect a fixed packet length. If you have any theories, I'd love to hear them. |
|
Yeah I've just checked in Wireshark and it fits your description perfectly. Are you sure everything before the As to theories, I'm noticing that the 8th hex value (starting from |
|
Oh wow thanks. I was going to say "sorry for the confusion, I meant that you shouldn't include the TCP packet metadata", but then I looked at |
|
Updated with b766439. I've now whittled them down to this:
I tried tearing out the Is it working with your device yet? |
|
I think the devices are expecting a special packet size. In my script I create a buffer with this size and put the data inside like this:
|
|
Okay I've done some analysis of these packets and have figured some stuff out: Prefix & Suffix The first half - 8 bytes The second half - The final value (the 16th byte of the whole prefix) is the size in bytes of the subsequent packet (obviously as a hex value). This is the length of the encrypted data in bytes plus the suffix - basically everything after the prefix. From my tests the suffix has always been 8 bytes. I have no idea how the suffix is created, but it doesn't seem to change anything and I've had good results leaving it as 000000000000aa55. I'm still not quite there with getting this working on these devices yet, but knowing how the prefix work feels like most of the heavy lifting. Connections & Broadcasts When the device is not connected, it sends out UDP broadcast packets to the network every 3-6 seconds. This contains plaintext JSON with the following information: This could be used as a way of enumerating devices on the network and all information other than the key. Furthering the enumeration aspect, we get a plaintext list of commands available on the device from the initial connection handshake: sending the One thing I've struggled with is actually decrypting the packets sent/received using the key. Has anyone got a deciphering script? |
|
@jepsonrob thanks, that's really helpful. Receiving Broadcasted MessagesFor anyone interested, you can receive the UDP broadcasted packets with a simple script:
I may add auto discovery functionality soon, although it's not a huge priority for me so if some else wants to do it and open a pull request I'd be very grateful. For Decrypting:Basically, just do the reverse of this:
I'll try to add a specific decryption function within the next couple days. |
|
@jepsonrob when you say, " not connected, it sends out UDP broadcast". Do you mean on the network but no devices are connected to it? I tried both @codetheweb 's suggested js listener script and a Python script based on SSDP discovery code on port 6666 and I'm not seeing anything. BTW thanks for excellent write ups, I now have a Python version, its rough and ready but works :-) https://github.com/clach04/python-tuya One thing I've noticed is that if there are spaces in the json payload, the device will not respond. Not an issue under js, but the Python stdlib library adds spaces. |
|
@clach04 - that's exactly what I mean, yep. It's potentially useful for enumeration because all devices on the network can see these packets in plaintext and they contain a bunch of useful information. And your issue with the JSON payload & spaces might come from the last 2 characters in the prefix - it needs to be the total length of the rest of the payload in hexadecimal. Using spaces will increase the size of the payload and if the value isn't the correct size then the command goes ignored. |
|
@jepsonrob thanks for the length info, that's it for sure. I added support for this in clach04/python-tuya@fc4612f - I'm not sure if its a single byte for length or not (I've only coded it for a single byte and I've not yet added sanity check for that in case the payload goes above 255 bytes). Thanks also for confirming about broadcast. Sadly, as per my previous comment, I'm not seeing this on my network (using code above i.e. something sitting on port 6666, I've not tried wiresharking the network). Any pointers? I've created a wiki https://github.com/clach04/python-tuya/wiki to store progress and other useful related docs. E.g. I figured out the timer for the SM-PW701U device. |
|
@clach04 - try using this python script and see if anything comes through: it's working for me! from socket import *
s=socket(AF_INET, SOCK_DGRAM)
s.bind(('',6666))
m=s.recvfrom(1024)
print m[0] And yeah I've only had it working for a single byte which is driving me crazy because the payload I need is over 255. Interestingly though, when I'm looking at the packets sent in Wireshark there's never anything over 255 bytes in size! I feel like this means I'm getting something wrong with my JSON payload and it's coming in too large, but I can't quite figure out how to decrypt the outgoing packets so I can't see the intended behaviour. Nice work on the python version by the way! That wiki is a useful resource - I'm going to write a no-stupid-questions type of tutorial for this we've got it working with other devices, probably just to help people with IFTTT integration, and I'll link out to that for further reading. |
|
@jepsonrob that script worked fine. My script also worked fine this morning (not sure why, maybe too tired last night). Interesting notes:
@jepsonrob script (slightly modified):
My script:
|
|
@jepsonrob for decrypting packets, try this (needs my Python module, https://github.com/clach04/python-tuya):
EDIT only supports 255 lengths (could be updated if it turns out protocol supports it. |
|
FYI, the UID is now no longer required when constructing an instance thanks to @jepsonrob. |
|
I read through #2 where accessing the Tuya API directly was briefly discussed. It would be preferable to be able to access the device IDs and localKeys without having to sniff traffic (especially since this appears to no longer be possible in recent versions of Android with the Packet Capture app). It is possible to retrieve the Android App's API Key and Secret from the app source code. I believe these are the values: However, I attempted to use the API documentation but was unable to successfully authenticate. Here's a fiddle that I was working with: https://dotnetfiddle.net/QzIVrP I think the problem may be with the signing. When I logcat the Tuya Android app I see that the "sign" parameter is 40 characters long, however according to the documentation it should only be 32 characters since it's just a hex string representing a 128-bit MD5 hash. Anyway, not sure if you'd want to fiddle around with it any more, but it really would be nice for the API to be able to fetch the device localKeys. |
|
@Marcus-L keep us posted. I'm going to be a bit of a nay-sayer and say that I suspect we do not need API access to the cloud to register the device and get an encryption key. My gut tells me that registration of the device can be figured out. RE packet capture problems, can you clarify which app/version and the problems you had? I'm using https://play.google.com/store/apps/details?id=com.xenon.jinvoo&hl=en v1.0.3 which appears to be the latest and still works for me with https://play.google.com/store/apps/details?id=app.greyshirts.sslcapture&hl=en - but I'm thinking I should back it up and post here! |
|
Forgot to add there is a chance the key is usable client side to interact with devices? I've not tried to decompile it (and probably won't have time), is that how you made this progress? |
|
Besides, this was intended to be a project to control devices entirely locally - no calling back to home. Sorry if that came off as a bit too stern. Maybe you're not planning to do that :). In any case, good luck mapping out the API. |
|
No worries @codetheweb, wasn't planning on hard-coding those keys into anything, Just exploring the API possibilities. As @clach04 mentioned it's likely to be possible to do everything locally. None of this would be necessary of course if the manufacturers would just release open tools, some documentation or even just rough specs! Or if the Tuya or Jinvoo app were to show the localKey settings. But here we are. |
|
OK, thanks for the clarification.
… On Dec 6, 2017, at 11:50, Marcus Lum ***@***.***> wrote:
No worries @codetheweb, wasn't planning on hard-coding those keys into anything, Just exploring the API possibilities. As @clach04 mentioned it's likely to be possible to do everything locally. None of this would be necessary of course if the manufacturers would just release open tools, some documentation or even just rough specs! Or if the Tuya or Jinvoo app were to show the localKey settings. But here we are.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
|
No problem, thanks for the useful protocol info. I did a rough port of the api to .NET Standard here: https://github.com/Marcus-L/m4rcus.TuyaCore I poked around a bit to try to see if I could find any more info on the discovery/localKeying process but didn't come up with anything useful. |
|
If you have a rooted Android phone, you can retrieve the settings from the app (Smart Life) data storage. The keys/configured devices are located at /data/data/com.tuya.smartlife/shared_prefs/dev_data_storage.xml There's a string in there (the only data) called "tuya_data". You need to html entity decode the string and it contains a JSON string (yes, this is slightly ridiculous). Inside the JSON string are the keys. |
|
Hi everyone, I just bought a couple of the outlets that work on this protocol but when I try to sniff the traffic using Charles, I don't get any GET requests like the ones mentioned here but only a few POST requests but it looks like the traffic is encrypted. I added tuyaus.com to the SSL Proxy in Charles but it did not help. I am not sure if it is the SSL encryption or Tuya is using their own encryption but it definitely looks like they changed the API or something like that. Or maybe I am doing something wrong. |
|
@nijave I'm not sure where you read |
|
The documentation from tuya themselves states the following:
Moreover it says:
If I get it right this means that there is a preset device specific key (the authKey). For the first communication during activation the first 8 byte(??) are used as AES encryption key. During the activation two other keys - the localKey AND the secKey- should be transmitted to the device. From there on secKey is used for HTTPS communication whereas localKey is used for MQTT communication. But that can't be correct as I cannot see the secKey anywhere. If the original app is able to retrieve the authKey from the devices, we should be able to do so also, don't we? |
|
Perhaps, but I doubt we can without also having an API key. |
This is basically described in https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP_DEPRECATED.md HttpCanary is used to capture the HTTPS POST requests from the Android app to the Tuya server. Then you can see to device ID and KEY in one of those post parameters when you add the device to the Android App. |
|
If attempting to get key from via: https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP.md#linking-a-tuya-device is it possible to also use the device from the smart life app? I understand both will reset the device which would create a new local key. Does that mean it is not possible? |
|
That is correct, currently there is not a good way to use your device with TuyaSmart and TuyAPI at the same time. |
|
At first I posted my own issue, but maybe this is not how things work around here, and you prefer questions of this sort over here? If so, apologies, I did not see any specific instructions to that effect. And it only took me 4 days to figure that out! In the meantime, I been working my way through this thread, but it's quite big thread... OK, anyway, here are my original 2 posts (copied): -- Hi guys, Thank you for all your great work on this project! And for sharing it!
If so, couple follow on questions:
Have I got all of this correct? Because I am very privacy conscious person, who refuse to use any devices that need to "phone home" in order to work. I had ordered some of these plugs with hopes of flashing Tasmota (or similar) on them, but unfortunately I learned that I bought some TW-02-based (WinnerMicro W600-based) devices which are not ESP8266 based, and therefore not supported by any alternative firmware. Leaving this way as perhaps one of only options for me (if I am understanding everything correctly). -- I guess my biggest concern would be creating the developer account. I really do not want to share any of my real personal information with Tuya (or anyone really who I feel doesn't need it, which is pretty much everyone What information do they ask for, and how thoroughly is it vetted (if at all)? Any feedback from anyone who has already done so would be greatly appreciated. -- |
|
I'm not 100% sure it's the same for your device - as it seems there are a LOT of different brands and version, but for me the instructions on https://github.com/codetheweb/tuyapi/blob/master/docs/SETUP_DEPRECATED.md worked perfectly fine. You can then extract the device ID and KEY you need to control the device from the POST parameters during the registration process. During the time I used this approach, I only found 1 mayor flaw: each time your device gets reset, you have to reconnect and the DeviceID/KEY will be different, so you have to redo the process, at which point the device do needs to phone home. A minor annoying part is that the IP address of the device changes every once and a while, and you have to scan the network again to find it. minor issue, maybe you even have a router where you can assign fixed IPs to devices. |
|
Thank you so much for the reply. I suppose now I see the wisdom in one big thread, where hundreds of people with similar interest all posted before and thereby also get notified of new posts. Like a mini forum, all on one thread. Brilliant! I have no problem with rooted or old versions of Android (have all of above, as well as other tools to potentially MitM), nor with transient IP address on LAN as I run OpenWRT router as well as dnsmasq, etc... However this "reset" issue concerns me, as it sounds sooner or later you will need to end up "phoning home" to Tuya? I suppose this is why the "developer account" method is now the recommended way. Is there any place I could find more information on what might cause this "reset"? Could I avoid any particular list of behaviors to make this not happen? In a reliable way? I already read about not using the Smart Life app in conjunction, also I suppose I would be blocking any "phoning home" at my router, would that be enough or are there more things to do? And even if I do all those things, will it be enough to prevent this "reset" and need to "phone home" again? Or, maybe I am still best just to get developer account? Any feedback on either route would still be very welcome. Happy Friday, everybody! |
Sorry, I've been busy with other stuff lately. I actually prefer new issues so it's easier for people in the future to search and find answers, but either works. |
|
How would I extract the IP of a device into a variable so that it could be printed to the console? |
With tuyapi/cli I guess? I never used the tool, but the following might be helpful (from README):
|
|
I have a Gosund / Tuya WiFi powerstrip. I created a Tuya login account, app, linked device and can successfully run But when I run I can control the powerstrip from iOS and Android apps. |
Doesn't it somehow "reset" your key or something when you do this? |
|
Looking through ~/.node-red/node_modules/tuyapi/index.js I see that it creates UDP listeners on ports 6666/6667 $ sudo firewall-cmd --permanent --add-port=6666/udp |
|
Watching UDP traffic on port 6667, I see periodic encrypted data from the powerstrip.
Turning debug on in the ~/.node-red/node_modules/tuyapi/index.js
|
|
Essentially, I can write a node app using the tuyapi to control the powerstrip successfully. Proved that it works! |
|
Hmm - node-red-contrib-tuya-smart has a hard dependency on tuyapi 3.2.3. I'll try to bump it to tuyapi 5.x |
|
I've given up on node-red-contrib-tuya-smart and have successfully configured node-red-contrib-tuya-local from |
|
Perhaps not the outcome you were looking for, but an (hopefully, workable) outcome nonetheless. Therefore, IMHO, the time was not "wasted." |
|
Once you have the keys, is it possible to remove the devices from the tuya app and keep using them with this project? |
|
Hi all, Ive tried running the provided example but device.find times out. I feel like I've been through all the trouble shooting I can find but it just wont connect. I have the device registered on the tuya cloud development platform and have used the tuya-cli wizard to get my devices key so I know its correct. What am I missing? (and yes the device is powered on with no other active connections). Thanks for any help! Edit: Running a tuya-cli get command also times out even though im using the info tuya-cli has provided me |
|
@beele if you extracted the keys after linking your device through the app, you cannot remove it. That will reset the device and invalidate the keys. @charliebudd if it works when you provide your IP address it's likely an issue with your network. Not much TuyAPI can do about it. If you still believe that there's a bug with TuyAPI, please open a new issue. |
|
So Ive used a packet sniffer (Wireshark) to isolate the traffic when I make a successful tuya-cli get call. When I run the synchronous sample script it stalls when connecting to device, neither timing out or erroring. In wire shark I see periodic traffic between my computer and the smart device while the script is awaiting the device.connect call. Im not much of a web developer so im struggling to debug the cause but this seams like odd behaviour. |
|
Please open a new issue with additional details if you believe there's a bug or want further support. A network dump would be helpful. |
How do I get a result like this in node red?? |
|
Hi, I created a few wrappers around this library to be used within python. The idea was that seen as this is consistently maintained, I wrote an IPC wrapper that uses file descriptors to communicate. The first github repo below shows my findings on how the roborock vacuum communicates, and the rest are the IPC node code, the python implementation for the IPC, a library for communicating via roborock, and finally a wrapper round it all to be used by home assistant. Hopefully it is useful to some other people out their too https://github.com/89jd/roborock_comms https://github.com/89jd/tuyapi-ipc https://github.com/89jd/pytuyapi-ipc |
|
Hello everyone, |
|
You only need the Tuya platform to access the data that lets you connect to the device (IP, ID, and Key if my memory is correct). This api uses a LAN connection so you will still be able to use your solution after your trial ends. |



I'm trying to get this to work with some smart bulbs and light strip, but currently the only missing piece for me is how you got the prefix & suffix in requests.json.
Are they just the packet header/footer or is there more to it than that?
Awesome work here by the way, thanks for all your work!