AlexxIT/go2rtc · error

wrong message checksum

Error message

wrong message checksum

What it means

Roborock IoT Decrypt integrity guard: the message passed the '1.0' prefix check, but the trailing CRC32 does not match the checksum of the body — the payload was corrupted or truncated in transit, or the framing is misaligned so the wrong bytes are treated as checksum.

Solutions

  1. Reconnect and retry the request; transient transport corruption is common
  2. Check for framing drift (short/long reads) in the connection reader
  3. Verify devKey correctness if corruption is persistent
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at pkg/roborock/iot/crypto.go:25 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/aae5f20a191c84be. Report an issue: GitHub.

Appendix: source

Thrown at pkg/roborock/iot/crypto.go:25

	"errors"
	"hash/crc32"
)

// key - convert timestamp to key
func (c *Codec) key(timestamp uint32) []byte {
	const salt = "TXdfu$jyZ#TZHsg4"
	key := md5.Sum([]byte(encodeTimestamp(timestamp) + c.devKey + salt))
	return key[:]
}

func (c *Codec) Decrypt(cipherText []byte) ([]byte, error) {
	if len(cipherText) < 32 || string(cipherText[:3]) != "1.0" {
		return nil, errors.New("wrong message prefix")
	}

	i := len(cipherText) - 4
	if binary.BigEndian.Uint32(cipherText[i:]) != crc32.ChecksumIEEE(cipherText[:i]) {
		return nil, errors.New("wrong message checksum")
	}

	if proto := binary.BigEndian.Uint16(cipherText[15:]); proto != 102 {
		return nil, nil
	}

	timestamp := binary.BigEndian.Uint32(cipherText[11:])
	return decryptECB(cipherText[19:i], c.key(timestamp)), nil
}

func (c *Codec) Encrypt(plainText []byte, seq, random, timestamp uint32) []byte {
	const proto = 101

	cipherText := encryptECB(plainText, c.key(timestamp))

	size := uint16(len(cipherText))

	msg := make([]byte, 23+size)

View on GitHub (pinned to c245815e75)