skip to content

In RADIUS over UDP, what does the shared secret between an access device and its server actually hide, and what travels in the clear?

level: middleimportance: must knowfreq 58%

answer

  1. one string, two ends, one address
  2. hides an attribute, not the packet
  3. the username rides in the clear
  4. MD5 keystream over User-Password (2) only
  5. no request integrity without Message-Authenticator (80)

basics

~20 s

A RADIUS shared secret hides only the User-Password (2) value, using an MD5 keystream. User-Name (1), NAS-IP-Address (4) and every other attribute travel in cleartext, and an Access-Request carries no integrity check unless Message-Authenticator (80) is present.

solid answer

~40 s

The shared secret is a symmetric string configured on the network access server and on the RADIUS server, selected by the client's source IP address. RFC 2865 puts it to exactly three uses: it seeds the MD5 keystream that hides the `User-Password (2)` value, it is appended to the input of the `Response Authenticator` digest so the access device can recognise a genuine reply, and it keys the HMAC when `Message-Authenticator (80)` is carried. Nothing else is protected. `User-Name (1)`, `NAS-IP-Address (4)`, `NAS-Port (5)`, `Calling-Station-Id (31)` and every returned attribute such as `Filter-Id (11)` or `Session-Timeout (27)` are readable by anyone on the path. The 16-octet `Request Authenticator` is a nonce, not a signature: without `Message-Authenticator (80)` an `Access-Request (Code 1)` has no keyed integrity at all.

code

pseudocode · 12 lines
pseudocode
Access-Request (Code 1)
  Identifier            = 37                     // clear
  Length                = 118                    // clear
  Request Authenticator = 16 unpredictable octets // clear (a nonce)
  Attributes:
    User-Name (1)          = "pump-op-14"        // clear
    User-Password (2)      = 32 hidden octets     // xor MD5 keystream
    NAS-IP-Address (4)     = 10.4.19.7            // clear
    NAS-Port (5)           = 3                    // clear
    NAS-Port-Type (61)     = Ethernet (15)        // clear
    Calling-Station-Id (31)= "AA-BB-CC-11-22-33"  // clear
    Message-Authenticator (80) = 16 octets        // HMAC-MD5, keyed by the secret

go deeper

for a junior

Fix the two ends first: an access device and a RADIUS server share a configured string, and it is not the user's password. That string is what makes the pair trust each other.

for a middle

Be able to name the one attribute the secret hides and three it does not, and to say that the Request Authenticator is a nonce rather than a signature.

for a senior

Reason from a capture: state exactly what one recorded Access-Request hands an attacker, and which of the three uses of the secret an offline guess would defeat.

for a principal

Frame it as an exposure you own rather than a setting: one hand-typed string keys three mechanisms across an estate, and the only durable answer is a transport change, not a longer string.

## What a RADIUS shared secret is A **RADIUS shared secret** is a symmetric string configured twice: once on the **network access server** — in RADIUS the *client* is the access device, never the end user's laptop — and once on the RADIUS server, in the entry describing that client. The server picks the secret by the **source IP address** the packet arrived from, so two access devices that present the same source address must be given the same secret. Nothing in the protocol negotiates it, rotates it, or proves it is fresh; it is typed in by hand at both ends and tends to stay there for the life of the equipment. It is **not** a session key, and it is **not** an encryption key for the packet. RFC 2865 and RFC 3579 put it to exactly three uses: 1. as the seed for the MD5 keystream that hides the `User-Password (2)` value; 2. as the trailing input to the `Response Authenticator` digest, which lets the access device recognise a reply that came from the server; 3. as the HMAC key for `Message-Authenticator (80)`, when that attribute is present in the packet. ## What is hidden Only the `User-Password (2)` value. The password is padded to a multiple of 16 octets and exclusive-ORed with an MD5 keystream derived from the secret `S` and the 16-octet `Request Authenticator` `RA`: `b1 = MD5(S + RA)`, `c(1) = p1 xor b1`, then `bi = MD5(S + c(i-1))` and `c(i) = pi xor bi`. That is a keystream, not a cipher, and the attribute's ceiling is 128 characters. Two near neighbours are commonly mistaken for it. `CHAP-Password (3)` is **not** hidden by the secret — it carries a response value computed by the user's device, and the secret plays no part in concealing it. RFC 2868 defines a separate, similar hiding for one of its tunnel attributes; that is its own construction and not this one. ## What travels in the clear | On the wire | Protected by the secret? | What an observer learns | |---|---|---| | `Code` / `Identifier` / `Length` | No | Which packet type, and which reply it pairs with | | `Request Authenticator` | No — it is a nonce | The keystream input for this request | | `User-Name (1)` | No | Who is attempting to log in | | `NAS-IP-Address (4)`, `NAS-Identifier (32)`, `NAS-Port (5)` | No | Which access device and which port | | `Calling-Station-Id (31)`, `Called-Station-Id (30)` | No | The endpoint's own address and the one it reached | | `NAS-Port-Type (61)` | No | The medium the attempt arrived on | | `User-Password (2)` | Hidden by the MD5 keystream | Only the password's padded length | | `Filter-Id (11)`, `Session-Timeout (27)` in a reply | No | The authorization the server granted | | `Message-Authenticator (80)` | It *is* the protection | That the sender held the secret | ## What the secret does not give you - **No confidentiality for the packet.** Everything above is plaintext, so a capture is a roster of accounts, devices and endpoint addresses. - **No integrity on a request** unless `Message-Authenticator (80)` is carried. The `Request Authenticator` is unkeyed; an on-path attacker can alter attributes and the server cannot tell. - **No per-message freshness beyond the `Identifier` and the nonce.** Duplicate suppression is a server-side cache decision, not a cryptographic guarantee. - **No key separation.** One string keys the keystream, the reply digest and the HMAC, so a guessed secret loses all three at once. - **No per-device isolation where addresses are shared.** Because selection is by source address, co-located clients share the secret and therefore share each other's exposure. ## Why this shapes operational practice On a shared medium — a field network where anyone with a receiver can hear the traffic — one capture of a single `Access-Request (Code 1)` yields four things: the account name, the access device and port it came from, the hidden password bytes, and the `Request Authenticator` that hid them. The last two together are the raw material for guessing the secret offline, at whatever rate the attacker's hardware allows, with no interaction with the server and nothing for the server to log. That is why the honest summary of RADIUS-over-UDP security is not "the secret protects the packet" but "the secret hides one attribute and lets each side recognise the other, and the strength of all of it is the strength of one hand-typed string plus MD5". The durable fixes are a long, random, per-device secret; `Message-Authenticator (80)` on every packet the deployment can put it on; and ultimately a transport that does the work instead — RADIUS over TLS on TCP port 2083 (RFC 6614) or RADIUS/DTLS on UDP port 2083 (RFC 7360), both Experimental.

  • Why must two RADIUS clients that send from the same source IP address be configured with the same shared secret?
    The server selects a client entry, and therefore a secret, by the source address of the arriving packet. If two access devices share an address — behind a translator, or two processes on one host — the server has no way to tell them apart before it verifies anything, so it can only apply one secret to both.
  • Does the Request Authenticator protect an Access-Request's integrity?
    No. It is an unpredictable, non-repeating 16-octet nonce that seeds the `User-Password (2)` keystream and that the reply's `Response Authenticator` is computed over. It involves no key on the request side, so it cannot detect a modified attribute. Keyed integrity on a request comes only from `Message-Authenticator (80)`.
  • If the secret hides so little, why is a long random secret still the standard advice on UDP?
    Because every remaining protection collapses to it. Guessing the secret from a capture is an offline computation whose only real cost is the search space, so length and randomness are the one parameter an operator still controls. It buys time; it does not add confidentiality to the attributes that were never hidden.

saying these in an interview costs you the question

  • Says the shared secret encrypts the whole RADIUS packet
  • Assumes the username is protected because the password is
  • Calls the Request Authenticator a signature over the request
  • Thinks a captured Access-Request tells an eavesdropper nothing useful
  • Believes two clients behind one source address can hold different secrets
  • Treats the shared secret as the end user's password