Cached at:
07/30/26, 01:45 AM
# Flume Water Monitor 915 MHz Signal Security – It’s Not Bad
Source: [https://waveformsecurity.com/blog/flume/](https://waveformsecurity.com/blog/flume/)
The Flume Water Monitor is a widely used consumer device that attaches to a home’s water meter and transmits near\-real\-time usage data to a companion bridge device on the home Wi\-Fi network\. The bridge then uploads the data to the cloud, where it is accessible via the Flume app\. The water\-meter\-sensor–\><–bridge link uses a 915 MHz band RF signal\. This link is encrypted, and**I was able to defeat the encryption with a few weeks of part\-time effort**, aided by the reverse\-engineering work published by Steve Crosby \[1\]\. Here’s a brief summary of what I did\.
### Finding and Demodulating the 915 MHz Band RF Signal
FCC documentation indicates the device uses a 50\-channel frequency\-hopping approach in the 902\.5–927 MHz band, with 500 kHz channel separation\. I tuned my LimeSDR Mini software defined radio to the center of the band \(using a 20 MHz display bandwidth\) and turned on the faucet\. Short\-duration \(~1 ms\) signals with ~500 kHz bandwidth were readily visible, as shown below\.
*Example Frequency Spectrum of Flume RF Message \(909 MHz center frequency\)*
After some experimentation, I determined that the signal uses**2\-FSK \(Frequency Shift Keying\) modulation at 200 kbps**\[2\], with a portion of the ~25\-byte messages whitened using an option in the sensor’s RFM69 transmitter chip\. Side note: the whitening sequence is poorly documented, but I believe it begins with FF 87 B8 89… \(see \[3\] for full sequence\)\.
The message structure is straightforward:

I validated the Cyclical Redundancy Check CRC\-16 values using the generator polynomial 0x1021 \(per the chipset documentation\) and with the initial seed and XOR options determined via exhaustive search\.
### What About the Encrypted Payload?
The 16\-byte payload is encrypted in AES\-128 Electronic Codebook \(ECB\) mode \(another RFM69 chipset option\)\. According to the raw data in Crosby’s post, the 128\-bit key is derived from an 8\-byte key using a simple hardcoded mapping\. While 64 bits is still too large to brute\-force directly, it turns out that a subset of**the RF message header bytes \(not encrypted\) provide another 16 bits of the key**\. This reduces the search space to 48 bits\. Adding the assumption \(inferred from Crosby’s data\) that half of the key’s last byte is a known constant further reduces it to 44 bits\.
I brute\-forced the remaining 44 unknown bits by testing multiple messages and looking for consistently low\-entropy plaintext \(or plaintexts with a high number of matching bits\)\. An unoptimized Python script on a decent GPU took roughly one day \(<$10 on a cloud platform\)\.
### Wrapping It Up
For a consumer water sensor, a frequency\-hopping waveform combined with 44\-bit effective encryption on the payload is not an unreasonable level of security\. That said, there is still some risk: with knowledge of the AES key, CRC algorithm, and other parameters, it becomes possible to generate spoofed messages\. These could potentially enable malicious firmware updates if over\-the\-air \(OTA\) updates are supported \(I have not investigated this and do not plan to\)\.
I reached out to Flume\. They were very responsive, and their CTO shared an overview of their already\-in\-progress plans to further improve the product’s privacy and security\. They are now comfortable with the release of this post\.
\[1\] \([https://lithostech\.com/2024/12/diving\-into\-flume\-water\-monitor/](https://lithostech.com/2024/12/diving-into-flume-water-monitor/)\)
\[2\] other signals with different data rates were also observed \(e\.g\. upon bridge reboot\)
\[3\] \([https://www\.nxp\.com/docs/en/application\-note/AN5070\.pdf](https://www.nxp.com/docs/en/application-note/AN5070.pdf)\)