[RADIATOR] Unicode in nthash passwords
Hosek, Ondrej
ondrej.hosek at tuwien.ac.at
Wed Apr 15 10:35:46 UTC 2026
Greetings,
there has been a push inside our university to allow characters beyond
the low-ASCII printables (U+0020 to U+007E) in passwords, as it is not
obvious to users why some special characters are allowed and some are
forbidden. Unfortunately, the authors of many protocol definitions have
decided to pretend that passwords are sequences of bytes, thereby
abdicating any responsibility for defining an encoding scheme, even
though passwords are generally submitted by users as text.
Thanks to long-standing background compatibility concerns regarding
MSCHAPv2 in conjunction with the thousands of non-centrally-managed
client devices of our students, we currently store our passwords in
nthash format. Lucky for us, MSCHAPv2 views the password as a sequence
of 0 to 256 Unicode characters and the NT hash is defined as one of the
building blocks in RFC 2759 (specifically section 8.3) to be the MD4
hash of the password. (The RFC omits that the password is to be encoded
specifically as "UTF-16 little-endian without byte order mark" before
it is passed to MD4, but the example in section 9.2 makes that a bit
more transparent.)
Unfortunately, Radiator's NT hash calculation is a tad naïve; it is
generally performed as follows:
Radius::MSCHAP::NtPasswordHash(Radius::MSCHAP::ASCIItoUnicode($pw))
where ASCIItoUnicode simply appends a 0x00 byte to each byte in $pw.
This is technically valid if the password is encoded according to ISO
8859-1, but not for any other encoding and certainly not for passwords
whose characters fall outside of this range.
I'd like to start a discussion on how to approach moving away from
this. The easiest option would be to rewrite ASCIItoUnicode to
interpret its argument as UTF-8 instead of ISO 8859-1, but this is
guaranteed to break compatibility with existing setups. A more flexible
alternative would be to allow administrators to specify the encoding of
incoming passwords for the purpose of NT hashing; I am not sure whether
this option would be best placed on a <Handler>, <Client>, <AuthBy> or
different level, but if the default is kept ISO 8859-1 and can be
reconfigured to UTF-8, this will probably solve the issue.
I tried arguing internally that characters beyond low-ASCII printables
are more trouble than they are worth, mostly because of the
aforementioned text-or-bytes issue, but this has fallen on deaf ears,
so I'm afraid "just say no" isn't going to be a solution here.
What do the other mailing list members think?
Kind regards,
~~ Ondra Hošek
TU Wien, network team
More information about the radiator
mailing list