Flume Water Monitor 915 MHz Signal Security – It’s Not Bad<br>Jul 28, 2026<br>Flume Water Monitor 915 MHz Signal Security – It’s Not Bad
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–>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 (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/)
[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)