SCNP25 supports per-channel voice encryption. Two pieces have to line up: the channel must have its secure flag set, and the codeplug must have a value in keyData. When a secure transmission is sent, the receiving voice service rejects the audio unless its own channel + key data combine to the same string the talker used.
This is not strong cryptography — it's a shared-secret routing tag designed to keep agencies' traffic separate from each other on the same backend. Treat keyData as you would treat any other shared system credential.
When PTT keys up on a secure channel, the client builds an RF channel string that bakes the key data into the routing identifier:
| Channel type | Plain (insecure) RF string | Secure RF string |
|---|---|---|
| Conventional | frequency:transmissionKey |
frequency:transmissionKey$keyData |
| Trunked | voiceFrequency |
voiceFrequency$keyData |
The voice service tunes to the resulting string. Receivers only hear the audio if they generate the same string locally — i.e. their own selected channel is also secure and shares the same key data.
The transmissionKey for conventional traffic is a UUID generated per transmission so receivers can detect when one talker's call ends.
keyData is a single string field on the codeplug. The default value is CHANGEME, which should be treated as "encryption is misconfigured":
keyData at CHANGEME will hear each other on secure channels.Set secure: true on a channel when:
keyData).Leave secure: false for channels meant to be heard by everyone — public dispatch monitors, mutual-aid talkgroups, conventional simplex, etc.