mschap
Requires the optional [mschap] extra (pip install pyrad2[mschap])
for the DES primitive. MD4 is bundled — see pyrad2._md4.
MS-CHAPv2 helpers (RFC 2759 + RFC 2548 §2.3).
MS-CHAPv2 is the challenge/response authentication scheme Microsoft
defined for PPP and Windows VPN clients. Plain RADIUS deployments
typically carry it as Microsoft VSAs (RFC 2548) on an Access-Request /
Access-Challenge pair; the EAP variant (EAP-MSCHAPv2) wraps the same
primitives in EAP framing and lives under pyrad2.eap.mschapv2.
Optional dependency. The DES step needed for the
ChallengeResponse primitive lives in the cryptography
package — install with::
pip install pyrad2[mschap]
MD4 (also required by MS-CHAPv2) is bundled in pyrad2._md4 because
modern OpenSSL builds no longer ship it. Both halves are loaded lazily
so the rest of pyrad2 stays importable even when the extra isn't
installed.
Security note. MS-CHAPv2 is cryptographically broken — the challenge/response primitive can be reduced to a single DES key search. Use it strictly for legacy interop, never as a primary authentication factor on a new deployment.
nt_password_hash(password)
Compute the NT Password Hash (RFC 2759 §8.3).
The Microsoft password hash is MD4(password_utf16le) — the
password is encoded as little-endian UCS-2/UTF-16 with no
terminator and no length prefix.
Source code in pyrad2/mschap.py
hash_nt_password_hash(password_hash)
Compute the PasswordHashHash (RFC 2759 §8.4).
Just MD4 applied to the 16-byte NT Password Hash. Used inside the Authenticator Response computation to prove the server also knew the password.
Source code in pyrad2/mschap.py
challenge_hash(peer_challenge, authenticator_challenge, user_name)
RFC 2759 §8.2 — SHA-1 truncated to 8 bytes.
user_name is the bare username — any domain prefix
(DOMAIN\user) is stripped by the caller per the spec.
Source code in pyrad2/mschap.py
challenge_response(challenge8, password_hash)
RFC 2759 §8.5 — 24-byte response from challenge + password hash.
Pads the 16-byte hash to 21 bytes, carves it into three 7-byte DES keys, and encrypts the 8-byte challenge under each. Returns the concatenated 24-byte result.
Source code in pyrad2/mschap.py
generate_nt_response(authenticator_challenge, peer_challenge, user_name, password)
RFC 2759 §8.1 — produce the 24-byte NT-Response.
The end-to-end primitive most callers want: takes the two 16-byte
challenges, the username, and the cleartext password, and returns
the 24 bytes that go into the Response field of
MS-CHAP2-Response (RFC 2548 §2.3.2) or the EAP-MSCHAPv2
response packet.
Source code in pyrad2/mschap.py
build_mschap2_response(ident, peer_challenge, nt_response, flags=0)
Build the 50-byte MS-CHAP2-Response VSA payload (RFC 2548 §2.3.2).
Wire layout::
Ident(1) | Flags(1) | Peer-Challenge(16) | Reserved(8) | Response(24)
The Reserved field is always 8 zero octets. Flags is 0 in
every conformant deployment — set non-zero only if a specific NAS
requires it.
Source code in pyrad2/mschap.py
generate_authenticator_response(password, nt_response, peer_challenge, authenticator_challenge, user_name)
RFC 2759 §8.7 — produce the 42-byte S=... authenticator response.
The server returns this in the MS-CHAP2-Success VSA (RFC 2548
§2.3.3); the client recomputes it locally and compares. The output
is an ASCII bytestring of the form b"S=" + 40 uppercase hex
characters — exactly what appears on the wire.
Source code in pyrad2/mschap.py
verify_authenticator_response(password, nt_response, peer_challenge, authenticator_challenge, user_name, received)
Validate the server's MS-CHAP2-Success Authenticator Response.
RFC 2548 §2.3.3 specifies the MS-CHAP2-Success VSA value as a
one-byte MS-CHAP-Identifier followed by the Success-Message
"S=<authenticator> M=<message>". This helper locates the
S= marker and compares the 42-byte authenticator slice against
the locally-recomputed expected value; M=<message> (an optional
operator-facing note) and any preceding identifier byte are
ignored.
Source code in pyrad2/mschap.py
prepare_mschap2_request(pkt, *, user_name, password, authenticator_challenge, peer_challenge, ident=0, flags=0)
Stamp an AuthPacket with the two MS-CHAPv2 VSAs and return the NT-Response.
Mutates pkt in place — User-Password is removed,
MS-CHAP-Challenge and MS-CHAP2-Response VSAs are set — and
returns the 24-byte NT-Response so the caller can later verify the
server's Authenticator Response without recomputing the chain.