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

Decrypting Razer to Tuya broadcast commands #464

Open
fu-raz opened this issue Feb 19, 2024 · 31 comments
Open

Decrypting Razer to Tuya broadcast commands #464

fu-raz opened this issue Feb 19, 2024 · 31 comments
Labels
enhancement New feature or request tuya_device Support for specific Tuya Devices

Comments

@fu-raz
Copy link

fu-raz commented Feb 19, 2024

LSC has recently released a string of products that can connect to Razer Synapse through an app. I've been trying to recreate the packets to be able to control these devices through software like SignalRGB. The problem is, I can't seem to decrypt the packets with the color data.

From what I've learned so far is:

  1. The devices use protocol v3.5. Because I can decrypt the broadcast packets that are coming from the device
  2. The LSC Battletron app communicates with the cloud API to get the available devices (you have to log using a QR code)
  3. Once the connection to razer is made, the app starts broadcasting to your local network .255. So it's not a direct to device connection

The packets that are broadcast use the same structure as the 3.5 protocol. So starting with 00006699 and ending with 00009966
If I follow the structure it seems to send the commands 00000005 and 00000010, not sure what they do.

I've tried numerous way to decrypt the package. I'm pretty sure it's just a JSON containing RGB values and maybe brightness. The LSC Battletron app (https://qr.lscsmartconnect.nl/software/BattletronDesktopDownload) does have a fairly extensive log file, which does show 'things', but I'm not sure if what I need is in there.

I have some captured packages that set my lamp to red, so I do know that the same package can work multiple times. I can post some example packets if anyone cares :)

Since these are broadcast packages (multiple devices should respond to the same command), I'm pretty sure (but not 100%) that they aren't encrypted using the local device key(s), but maybe I'm wrong and that's the solution to all of this.

Does anyone have any experience with this?

@fu-raz fu-raz changed the title Decrypting Razer broadcast commands Decrypting Razer to Tuya broadcast commands Feb 19, 2024
@uzlonewolf
Copy link
Collaborator

While I'm not familiar with this system, I'd love to take a look at it if you could post some packet captures.

@fu-raz
Copy link
Author

fu-raz commented Feb 20, 2024

Thanks for your interest!

These are some of the 00000005 commands I found in the log file. In the log bfc855c37fb4ab51e4n80d is the device id of the lamp I'm testing.

[2024-02-15T18:47:50.098] [WARN] default - 未通过udp解析 devId为空
[2024-02-15T18:47:50.113] [INFO] default - 开始验签
[2024-02-15T18:47:50.113] [INFO] default - apiRequest dll loaded
[2024-02-15T18:47:50.114] [INFO] default - 验签结果 52a9e2bb0bcf4fee6795d640959d00fe
[2024-02-15T18:47:50.114] [INFO] default - 开始解密 1b49ca2806e1afa1
[2024-02-15T18:47:50.115] [INFO] default - 解密完成
[2024-02-15T18:47:52.051] [INFO] default - SendBroadcast 发送UDP广播 00000005 0000669900000000000100000005898fe93c000000660000000106a12be6049d351b8391e3adf4f59c6e0000002405a92e53ba101a53d0c885da4fec83f44e514b0211de28cb4d48496bad1028774a3dbf86fb9d8d75246c6cb6171d23d54ae30a8500009966
[2024-02-15T18:47:52.051] [INFO] default - 进行协商 bfc855c37fb4ab51e4n80d
[2024-02-15T18:47:52.051] [INFO] default - 业务数据立即下发
[2024-02-15T18:47:52.051] [INFO] default - 开始协商
[2024-02-15T18:47:52.051] [WARN] default - 未通过udp解析 devId为空
[2024-02-15T18:47:54.037] [INFO] default - 进行协商 bfc855c37fb4ab51e4n80d
[2024-02-15T18:47:54.037] [INFO] default - 业务数据立即下发
[2024-02-15T18:47:54.037] [INFO] default - 开始协商
[2024-02-15T18:47:54.037] [WARN] default - 未通过udp解析 devId为空
[2024-02-15T18:47:54.051] [INFO] default - SendBroadcast 发送UDP广播 00000005 0000669900000000000200000005898fe93c00000066000000012d55bee99f74ff4279a48393f4f59c6e000000247dd323397ff0d8a2b37bc52aaf239261454157bd94394318d34053b9765f3614a6f4f67f30465149f6dc9717b5f2607969521fa100009966
[2024-02-15T18:47:56.036] [INFO] default - 进行协商 bfc855c37fb4ab51e4n80d
[2024-02-15T18:47:56.036] [INFO] default - 业务数据立即下发
[2024-02-15T18:47:56.037] [INFO] default - 开始协商
[2024-02-15T18:47:56.037] [WARN] default - 未通过udp解析 devId为空
[2024-02-15T18:47:58.037] [INFO] default - 进行协商 bfc855c37fb4ab51e4n80d
[2024-02-15T18:47:58.038] [INFO] default - 业务数据立即下发
[2024-02-15T18:47:58.038] [INFO] default - 开始协商
[2024-02-15T18:47:58.038] [INFO] default - SendBroadcast 发送UDP广播 00000005 0000669900000000000400000005898fe93c00000066000000012e52a20f3d580446c6042d66f4f59c6e00000024fad953ae8ef04487ad89e8fb08cf144ac49448011372cff50c064bb055ddd6d22439e86e90cb8706cdd72f780374ed92cf4aefb800009966
[2024-02-15T18:47:58.038] [WARN] default - 未通过udp解析 devId为空

These are 00000010 commands that set the color of the device.
Blue:
0000669900000000489400000010f0be9c1e0000004a00000001f909fe8ec787320fc238d0464043308800000008a4995a69443e2b17537bb1a9da44cb8d57ff47b049f8c82900009966

Red:
0000669900000000491d00000010f0be9c1e0000004a00000001d99cdea616946349e8878e62404330880000000860c88e61d86a7025ba52f48bc9d67e32590c7bc8ac0938ea00009966

@fu-raz
Copy link
Author

fu-raz commented Feb 20, 2024

I'll see if I can find another light that supports this protocol so I can compare having a single or multiple devices

@uzlonewolf
Copy link
Collaborator

uzlonewolf commented Feb 22, 2024

Unfortunately the protocol is similar but not the same as the normal 6699 one.

00006699 0000 00004894 00000010 f0be9c1e 0000004a 00000001 f909fe8ec787320fc238d046 40433088 00000008 a4995a69443e2b17 537bb1a9da44cb8d57ff47b049f8c829 00009966
00006699 0000 0000491d 00000010 f0be9c1e 0000004a 00000001 d99cdea616946349e8878e62 40433088 00000008 60c88e61d86a7025 ba52f48bc9d67e32590c7bc8ac0938ea 00009966
00006699 0000 00000002 00000005 898fe93c 00000066 00000001 2d55bee99f74ff4279a48393 f4f59c6e 00000024 7dd323397ff0d8a2b37bc52aaf239261454157bd94394318d34053b9765f3614a6f4f67f 30465149f6dc9717b5f2607969521fa1 00009966
00006699 0000 00000004 00000005 898fe93c 00000066 00000001 2e52a20f3d580446c6042d66 f4f59c6e 00000024 fad953ae8ef04487ad89e8fb08cf144ac49448011372cff50c064bb055ddd6d22439e86e 90cb8706cdd72f780374ed92cf4aefb8 00009966

Using the first one as an example, it breaks down as:
00006699 0000 prefix
00004894 sequence number
00000010 command id
f0be9c1e source id
0000004a total packet length
00000001 number of target devices (max 5)
f909fe8ec787320fc238d046 per-packet IV/nonce
40433088 first target device id
00000008 first target device encrypted data length
a4995a69443e2b17 first target device encrypted data
537bb1a9da44cb8d57ff47b049f8c829 first target device AES-GCM tag
(repeat "target device id" through "target device AES-GCM tag" fields as needed, up to 5)
00009966 footer

I assume the client logs into each device the normal way and registers a shared key with it before using said key for broadcasts, but I'm not positive. Back when I was adding support for protocol 3.5 I remember seeing some stuff for UDP commands when I was poking around the gateway firmware in ghidra but didn't really dig into it at the time. I'll see if I can find it again.

@fu-raz
Copy link
Author

fu-raz commented Feb 23, 2024

I wanted to give an update on this. I've recently been able to get the full source code for their app, since they didn't delete the source maps when they published it. So the packet is no longer a mystery to me hahah! I've been able to add my own logging to their official app, so I can now easily see what they encrypt and how, using which keys etc.

It seems that the broadcast packet contains the data for all the lights and they encrypt the data for each light with a device specific key and the same nonce for all devices in the packet. The result of that is just concatenated in the broadcast packet and how many devices there are and the length of their individual packet is stored in part of the broadcast packet as well.

Some lights only support one color and will only receive one color, some support more colors and receive more colors in the data (because it's connected to razer they get only 4, but who knows if they support more). The keys used per device are saved in the local storage of the application. I'm still figuring out if this is a key that is negotiated with the device or if it's the actual private key of the device.

The color data being sent is this
[ { devId: 'bf93e33ea63bd815fcsffh', value: '0004000003e80366000003e80366000003e80366000003e803660003010101' }, { devId: 'bfc855c37fb4ab51e4n80d', value: '0000645700000100' } ]

Where the first device supports multiple colors and the second device only one. I'm pretty sure 000003e80366 in the first color values is the color. Haven't looked into it, but maybe this is familiar to you?

I'll keep you posted :)

@uzlonewolf
Copy link
Collaborator

Ooooh, interesting! Any tips on how to extract the source maps?

The color is usually sent as HSV with the S and V multiplied by 10; 0000 03e8 0366 = hue = 0, saturation = 1000 = 100.0%, value = 870 = 87.0%. A HSV/RGB converter can be found in BulbDevice.

That full value string looks similar but slightly different than the normal BulbDevice scene string. I'm not sure what those bytes trailing the color data are for.

@uzlonewolf
Copy link
Collaborator

I'm still interested in hearing how you did it, but I think I also got it figured out.

It looks like command 0x05 packets are encrypted with the fixed key '6f36045d84b042e01e29b7c819e37cf7' and consist of 4 bytes of 0x00 followed by a 16-byte token and finally a 16-byte random number. It then expects a command 0x06 response containing a hmac and the session key. It then uses this negotiated session key to encrypt command 0x10 data.

@fu-raz
Copy link
Author

fu-raz commented Feb 23, 2024

If you install the app I linked, you'll have to look for the app.asar file located in AppData\Local\Programs\LSC_Battletron\resources

You'll need to extract the contents. I used NodeJS and the command npx @electron/asar extract .\app.asar .\app. Then you get all the contents of the app. I then used https://github.com/denandz/sourcemapper to restore the files and file structure.

@uzlonewolf
Copy link
Collaborator

Ah, that's really close to what I did, except I used npx uglify-js input.js -b --source-map "filename='input.js.map'" -o output.js to un-minify.

@uzlonewolf
Copy link
Collaborator

And you actually don't need to install the app, 7z extracts it without needing to install. Which is good as I run Linux and wasn't looking forward to seeing how well it works under Wine 🤣

@fu-raz
Copy link
Author

fu-raz commented Feb 23, 2024

I'm still interested in hearing how you did it, but I think I also got it figured out.

It looks like command 0x05 packets are encrypted with the fixed key '6f36045d84b042e01e29b7c819e37cf7' and consist of 4 bytes of 0x00 followed by a 16-byte token and finally a 16-byte random number. It then expects a command 0x06 response containing a hmac and the session key. It then uses this negotiated session key to encrypt command 0x10 data.

This seems to be the case indeed! I think the trailing bytes are a checksum. Other devices I've decrypted usually use something like a XOR checksum. But I could be wrong

@fu-raz
Copy link
Author

fu-raz commented Feb 23, 2024

I was wrong.. It's data that tells the device about how many zones there are and their length. You can find it in the App.vue file

@fu-raz
Copy link
Author

fu-raz commented Feb 29, 2024

I've been working this out and I've figured out almost everything (I will make a new repo soon with my test project), but unfortunately we still need the local key for each device.

@Lemec23234
Copy link

Hi, I'm a person who stumbled upon this conversation, I own a razer chroma Battletron light bar and would like it to work with the signalRGB app or another RGB app. I'd love if you could operate the LED bars with an SignalRGB or any other app like OpenRGB.

@fu-raz
Copy link
Author

fu-raz commented Feb 29, 2024

Hi, I'm a person who stumbled upon this conversation, I own a razer chroma Battletron light bar and would like it to work with the signalRGB app or another RGB app. I'd love if you could operate the LED bars with an SignalRGB or any other app like OpenRGB.

I'm working on it! The problem I'm having right now is that you NEED the local key of each device to communicate with them. So I'm currently working on implementing the official tuya api to get this up and running. If you already have the keys to your devices (or know how to get them) you will be able to test the plugin for signalrgb soon

@Lemec23234
Copy link

I have no experience with this, I hope you can find a way to get the local keys of the devices as I have no idea how to get them. I'm still going to try to find a way to find the local keys of the devices.

@Lemec23234
Copy link

I'm working on it! The problem I'm having right now is that you NEED the local key of each device to communicate with them. So I'm currently working on implementing the official tuya api to get this up and running. If you already have the keys to your devices (or know how to get them) you will be able to test the plugin for signalrgb soon.

I managed to get the local key of the battletron light bar, so I could test your signalRGB plugin. Is that the local keys are changed at each connection or the local key is unique for each device ?

@uzlonewolf uzlonewolf added enhancement New feature or request tuya_device Support for specific Tuya Devices labels Mar 3, 2024
@uzlonewolf
Copy link
Collaborator

Local keys are unique for each device. Devices use these local keys to negotiate session keys for each connection.

@uzlonewolf
Copy link
Collaborator

If you are not going to be using TinyTuya's cloud functions and only need the local keys then you can use something like https://github.com/blakadder/tuya-uncover to get them without needing to sign up for a developer account.

@Lemec23234
Copy link

I have a problem with the battletron led bar, when I control the led bar with razer chroma, the led bar has a very low frame rate to change color. I don't know if the problem is with my wifi network or the LSC_battletron app. But I think it's coming from the app because normally, if I understand correctly, the data goes through the tuya cloud and then to the battletron led bar, I think it affects the frame rate to change color.

@Lemec23234
Copy link

I have a quick question for the SignalRGB plugin, we will be able to control the leds individually or controlled only 4 leds like in razer synapse ?

@Lemec23234
Copy link

Will this lightbar battletron be compatible with tinytuya in the future ?

@uzlonewolf
Copy link
Collaborator

It sounds like @fu-raz is making a signalrgb plug-in, no idea if they're also adding it to TinyTuya or not. I can add it to TinyTuya if they don't. Unfortunately the postal service is taking their sweet time delivering the light bar I ordered for testing.

@Lemec23234
Copy link

It sounds like @fu-raz is making a signalrgb plug-in, no idea if they're also adding it to TinyTuya or not. I can add it to TinyTuya if they don't. Unfortunately the postal service is taking their sweet time delivering the light bar I ordered for testing.

Maybe @fu-raz does the signalRGB plugin. A SignalRGB developer told me that tuya devices are on the list of wifi devices that will be added in the very distant future. However, I don't know if the battletron's light bars will be compatible. Hopefully @fu-raz will give you some news about the SignalRGB plugin battletron lighbars.

@Lemec23234
Copy link

I saw that furaz created a signalRGB plugin! I'm going to try it soon!

@fu-raz
Copy link
Author

fu-raz commented Mar 19, 2024

Sorry I haven't been very active here. I finally managed to make this work in a node js project. The problem I run into is that I not only need the local key, but I also need the product Id. There's a white list with products that can be used and right now there's no other way of determining if the device supports the razer protocol.

I will post the test project on my github if you're interested.
https://github.com/fu-raz/nodejs-tuya-razer

@fu-raz
Copy link
Author

fu-raz commented Mar 19, 2024

I saw that furaz created a signalRGB plugin! I'm going to try it soon!

This is a very very early test project, no where near working. I'm working with the devs on Discord to get certain features to make this work. But I'm having trouble decrypting the messages using plain javascript. I don't have access to actual Crypto functions, so I have to rely on projects like https://github.com/Hinaser/jscrypto/ to get GCM working. So far it's not haha!

@Lemec23234
Copy link

Lemec23234 commented Mar 19, 2024

Sorry I haven't been very active here. I finally managed to make this work in a node js project. The problem I run into is that I not only need the local key, but I also need the product Id. There's a white list with products that can be used and right now there's no other way of determining if the device supports the razer protocol.

I will post the test project on my github if you're interested. https://github.com/fu-raz/nodejs-tuya-razer

Hello, I was a little interested in your nodejs project, I would like to know how to install , I think it is easy.
Can you tell how to use your nodejs project ?

@uzlonewolf
Copy link
Collaborator

Well, my light bar finally came in, but I'm super busy and it's going to be a while before I can get to it.

Are you planning on adding support to TinyTuya, @fu-raz ?

@Lemec23234
Copy link

hello ! @uzlonewolf
I hope your light bar works correctly with Razer because it's quite the opposite, the effects are not smooth at all, there is 1 second of latency between Razer and the light bar. If you can help me resolve this problem that would be great. Even searching the internet for the problem, I can't find it, no one talks about the problem between Razer and the light bar.

@fu-raz
Copy link
Author

fu-raz commented Apr 1, 2024

Well, my light bar finally came in, but I'm super busy and it's going to be a while before I can get to it.

Are you planning on adding support to TinyTuya, @fu-raz ?

I've never programmed anything in Python, so I don't think that's a good idea. But might be a nice challenge for when I get everything up and running. I'd be willing to test though. I have the light bar and also the ball

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request tuya_device Support for specific Tuya Devices
Projects
None yet
Development

No branches or pull requests

3 participants