RFC 2433
Microsoft PPP CHAP Extensions
Microsoft PPP CHAP Extensions ๐
- RFC: 2433
- Series: Network Working Group
- Authors: G. Zorn and S. Cobb, both at Microsoft Corporation ๐ป
- Category: Informational
- Date: October 1998
- Obsoletes / Updates: The header doesn't list any RFCs that this one obsoletes or updates ๐ธ
Status of This Memo โจ
Okay so this memo gives information to the Internet community. It does not specify an Internet standard of any kind ๐ง Distribution is unlimited, so share it with everyone!
Copyright Notice ๐ฆ
Copyright (C) The Internet Society (1998). All Rights Reserved. ๐
IESG Note ๐จ
The protocol described here has significant vulnerabilities. People planning on implementing or using this protocol should read section 12, "Security Considerations". ๐ญ
1. Abstract โจ
Okay, so PPP [1] is the standard way to send multi-protocol datagrams over point-to-point links ๐ It also has an extensible Link Control Protocol and a whole family of Network Control Protocols (NCPs) for setting up and configuring different network-layer protocols. Iconic behaviour from PPP, honestly ๐
This document describes Microsoft's PPP CHAP dialect, called MS-CHAP. It extends the user authentication that Windows networks already offer so it works for remote workstations ๐ MS-CHAP is closely derived from the PPP Challenge Handshake Authentication Protocol in RFC 1994 [2], so keep that one handy, bestie ๐
The algorithms used to generate the various MS-CHAP protocol fields are described in an appendix. ๐
2. Introduction ๐ธ
Microsoft made MS-CHAP to authenticate remote Windows workstations. It gives you the same experience LAN users are used to, and it uses the encryption and hashing algorithms that Windows networks already use ๐ฆ
Where possible, MS-CHAP matches standard CHAP. The main differences between MS-CHAP and standard CHAP are:
- MS-CHAP is enabled by negotiating CHAP Algorithm 0x80 in LCP option 3, Authentication Protocol.
- The MS-CHAP Response packet is in a format designed for compatibility with Microsoft's Windows NT 3.5, 3.51 and 4.0, and Windows95 networking products. The MS-CHAP format does not require the authenticator to store a clear-text or reversibly encrypted password. That's a big deal ๐
- MS-CHAP provides authenticator-controlled authentication retry and password changing mechanisms. ๐
- MS-CHAP defines a set of reason-for-failure codes returned in the Failure packet Message field. ๐
3. Specification of Requirements ๐
In this document, the key words "MAY", "MUST, "MUST NOT", "optional", "recommended", "SHOULD", and "SHOULD NOT" are to be interpreted as described in [2]. These are the official requirement words, so read them carefully, bestie ๐ซถ
4. LCP Configuration ๐ง
The LCP configuration for MS-CHAP is identical to the one for standard CHAP. The only difference is that the Algorithm field has the value 0x80, instead of the MD5 value 0x05. PPP implementations that don't support MS-CHAP, but that correctly implement LCP Config-Rej, should have no problem dealing with this non-standard option. โจ
5. Challenge Packet ๐
The MS-CHAP Challenge packet is identical in format to the standard CHAP Challenge packet. Easy ๐
MS-CHAP authenticators send an 8-octet challenge Value field. Peers don't need to copy Microsoft's algorithm for picking the 8-octet value. The standard guidelines on randomness [1,2,7] SHOULD be observed, though. ๐ฒ
Microsoft authenticators don't currently put anything in the Name field. This may change in the future. ๐ฎ
6. Response Packet ๐
The MS-CHAP Response packet is identical in format to the standard CHAP Response packet. The main difference is that the Value field is sub-formatted differently, like this:
24 octets: LAN Manager compatible challenge response
24 octets: Windows NT compatible challenge response
1 octet : "Use Windows NT compatible challenge response" flag
The LAN Manager compatible challenge response is an encoded function of the password and the received challenge. It's output by the routine LmChallengeResponse() (see section A.1, below). LAN Manager passwords are limited to 14 case-insensitive OEM characters. Also, use of the LAN Manager compatible challenge response has been deprecated, so peers SHOULD NOT generate it, and the sub-field SHOULD be zero-filled. The algorithm used to generate the LAN Manager compatible challenge response is described here for informational purposes only. ๐
The Windows NT compatible challenge response is an encoded function of the password and the received challenge too. It's output by the routine NTChallengeResponse() (see section A.5, below). A Windows NT password is a string of 0 to (theoretically) 256 case-sensitive Unicode [8] characters. Current versions of Windows NT limit passwords to 14 characters, mainly for compatibility reasons. This may change in the future. ๐
The "use Windows NT compatible challenge response" flag, if 1, means the Windows NT response is provided and should be used in preference to the LAN Manager response. The LAN Manager response will still be used if the account doesn't have a Windows NT password hash. For example, that happens if the password hasn't been changed since the account was uploaded from a LAN Manager 2.x account database. If the flag is 0, the Windows NT response is ignored and the LAN Manager response is used. Since LAN Manager authentication has been deprecated, this flag SHOULD always be set (1), and the LAN Manager compatible challenge response field SHOULD be zero-filled. ๐ฅ
The Name field identifies the peer's user account name. The Windows NT domain name may come before the user's account name. For example, BIGCO\johndoe where "BIGCO" is a Windows NT domain containing the user account "john-doe". If a domain is not provided, the backslash should also be left out, like johndoe. ๐งฉ
7. Success Packet ๐
The Success packet is identical in format to the standard CHAP Success packet. Nothing new here, just vibes โจ
8. Failure Packet ๐ซ
The Failure packet is identical in format to the standard CHAP Failure packet. But here's the twist: there's formatted text stored in the Message field, and, contrary to the standard CHAP rules, that text affects the protocol ๐ The Message field format is:
"E=eeeeeeeeee R=r C=cccccccccccccccc V=vvvvvvvvvv"
Here's what each part means:
- The "eeeeeeeeee" is the decimal error code (it doesn't need to be 10 digits). It corresponds to one of the codes listed below. Implementations should deal with codes that aren't on this list gracefully. ๐งธ
646 ERROR_RESTRICTED_LOGON_HOURS
647 ERROR_ACCT_DISABLED
648 ERROR_PASSWD_EXPIRED
649 ERROR_NO_DIALIN_PERMISSION
691 ERROR_AUTHENTICATION_FAILURE
709 ERROR_CHANGING_PASSWORD
- The "r" is a flag set to "1" if a retry is allowed, and "0" if not. When the authenticator sets this flag to "1", it disables short timeouts. It expects the peer to prompt the user for new credentials and resubmit the response. โณ
- The "cccccccccccccccc" is 16 hexadecimal digits, shown as an ASCII representation of a new challenge value. This field is optional. If it isn't sent, the authenticator expects the resubmitted response to be calculated based on the previous challenge value plus decimal 23 in the first octet, i.e. the one immediately following the Value Size field. Windows 95 authenticators may send this field. Windows NT authenticators don't, but they may in the future. Both systems implement peer support for this field. ๐
- The "vvvvvvvvvv" is the decimal version code (it doesn't need to be 10 digits). It indicates the MS-CHAP protocol version supported on the server. Right now, this only matters for selecting a Change Password packet type. If the field isn't present, the version should be assumed to be 1. Since use of the version 1 Change Password packet has been deprecated, this field SHOULD always contain a value greater than or equal to 2. ๐
Implementations should accept but ignore any additional text they don't recognize. ๐ซถ
9. Change Password Packet (version 1) ๐
The version 1 Change Password packet doesn't appear in standard CHAP. It lets the peer change the password on the account specified in the previous Response packet. The version 1 Change Password packet should be sent only if the authenticator reports ERROR_PASSWD_EXPIRED (E=648) and V is either missing or equal to one in the Message field of the Failure packet. ๐
The use of the Change Password Packet (version 1) has been deprecated. Its format is described here for informational purposes, but peers SHOULD NOT transmit it. ๐ซ
The format of this packet is as follows:
1 octet : Code (=5)
1 octet : Identifier
2 octets: Length (=72)
16 octets: Encrypted LAN Manager Old password Hash
16 octets: Encrypted LAN Manager New Password Hash
16 octets: Encrypted Windows NT Old Password Hash
16 octets: Encrypted Windows NT New Password Hash
2 octets: Password Length
2 octets: Flags
Here's what each field does:
- Code: 5
- Identifier: The Identifier field is one octet and helps match requests and replies. Its value is the Identifier of the received Failure packet this packet responds to, plus 1.
- Length: 72
- Encrypted LAN Manager New Password Hash and Encrypted LAN Manager Old Password Hash: These fields contain the LAN Manager password hash of the new and old passwords, encrypted with the last received challenge value. This is output by the routine LmEncryptedPasswordHash() (see section A.8, below).
- Encrypted Windows NT New Password Hash and Encrypted Windows NT Old Password Hash: These fields contain the Windows NT password hash of the new and old passwords, encrypted with the last received challenge value. This is output by the pseudo-code routine NtEncryptedPasswordHash() (see section A.10, below). ๐ง
- Password Length: The length in octets of the LAN Manager compatible form of the new password. If this value is greater than or equal to zero and less than or equal to 14, it's assumed the encrypted LAN Manager password hash fields are valid. Otherwise, it's assumed these fields aren't valid. In that case, the Windows NT compatible passwords MUST be provided. ๐จ
- Flags: This field is two octets long. It's a bit field of option flags, where 0 is the least significant bit of the 16-bit quantity:
- Bit 0: If this bit is set (1), it means the encrypted Windows NT hashed passwords are valid and should be used. If this bit is cleared (0), the Windows NT fields aren't used and the LAN Manager fields must be provided. ๐
- Bits 1-15: Reserved, always clear (0). ๐
10. Change Password Packet (version 2) ๐
okay bestie, this one is the version 2 Change Password packet and it is NOT in standard CHAP ๐
It lets the peer change the password on the account named in the previous Response packet. You should only send it if the authenticator reports ERROR_PASSWD_EXPIRED (E=648) and a version of 2 or greater in the Message field of the Failure packet. โจ
This packet type is supported by Windows NT 3.51, 4.0 and recent versions of Windows 95 ๐ฆ It is not supported by Windows NT 3.5 or early versions of Windows 95 ๐
Here's the layout of the packet ๐ง
1 octet : Code
1 octet : Identifier
2 octets : Length
516 octets : Password Encrypted with Old NT Hash
16 octets : Old NT Hash Encrypted with New NT Hash
516 octets : Password Encrypted with Old LM Hash
16 octets : Old LM Hash Encrypted With New NT Hash
24 octets : LAN Manager compatible challenge response
24 octets : Windows NT compatible challenge response
2-octet : Flags
Code
The Code value is 6 ๐ธ
Identifier
The Identifier is one octet and helps match requests with replies ๐ซถ Its value is the Identifier of the received Failure packet this one answers, plus 1.
Length
The Length is 1118 ๐ฅ
Password Encrypted with Old NT Hash
This field holds the PWBLOCK form of the new Windows NT password, encrypted with the old Windows NT password hash. It's the output of the NewPasswordEncryptedWithOldNtPasswordHash() routine (see section A.11, below) ๐
Old NT Hash Encrypted with New NT Hash
This field holds the old Windows NT password hash, encrypted with the new Windows NT password hash. It's the output of the OldNtPasswordHashEncryptedWithNewNtPasswordHash() routine (see section A.14, below) ๐
Password Encrypted with Old LM Hash
This field holds the PWBLOCK form of the new Windows NT password, encrypted with the old LAN Manager password hash. It's the output of the NewPasswordEncryptedWithOldLmPasswordHash() routine described in section A.15, below. BUT the use of this field has been deprecated ๐ peers SHOULD NOT generate it, and this field SHOULD be zero-filled.
Old LM Hash Encrypted With New NT Hash
This field holds the old LAN Manager password hash, encrypted with the new Windows NT password hash. It's the output of the OldLmPasswordHashEncryptedWithNewNtPasswordHash() routine (see section A.16, below). Same deal though, the use of this field has been deprecated ๐ญ peers SHOULD NOT generate it, and this field SHOULD be zero-filled.
LAN Manager compatible challenge response
Windows NT compatible challenge response
This is the challenge response field (the same one described in the Response packet), but calculated on the new password and the same challenge that was used in the last response ๐ The LAN Manager compatible challenge response is deprecated too, so peers SHOULD NOT generate it, and the field SHOULD be zero-filled.
Flags
This field is two octets long ๐ฆ It's a bit field of option flags, where 0 is the least significant bit of the 16-bit quantity. Here's how it's laid out:
1
5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Bit 0: this is the "use Windows NT compatible challenge response" flag, same as in the Response packet ๐
- Bit 1: if it's set (1), the "Password Encrypted with Old LM Hash" and "Old LM Hash Encrypted With New NT Hash" fields are valid and should be used. If it's clear (0), those fields are not valid. This bit SHOULD always be clear (0) ๐ โโ๏ธ
- Bits 2-15: reserved, always clear (0) ๐
11. Security Considerations ๐
okay this part is SERIOUS bestie, don't skip it ๐ญ As an implementation detail, the authenticator SHOULD limit the number of password retries allowed, so brute-force password guessing attacks are harder to pull off ๐
The challenge value gets encrypted with the password hash to form the response, and the challenge is sent in clear text. That means both passive known-plaintext and active chosen-plaintext attacks against the password hash are possible ๐จ Suitable precautions (i.e., frequent password changes) SHOULD be taken in environments where eavesdropping is likely.
The Change Password (version 1) packet is vulnerable to a passive eavesdropping attack that can easily reveal the new password hash ๐ For this reason, it MUST NOT be sent if eavesdropping is possible.
12. References ๐
[1] Simpson, W., "The Point-to-Point Protocol (PPP)", STD 51, RFC 1661, July 1994.
[2] Simpson, W., "PPP Challenge Handshake Authentication Protocol (CHAP)", RFC 1994, August 1996.
[3] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
[4] "Data Encryption Standard (DES)", Federal Information Processing Standard Publication 46-2, National Institute of Standards and Technology, December 1993.
[5] Rivest, R., "MD4 Message Digest Algorithm", RFC 1320, April 1992.
[6] RC4 is a proprietary encryption algorithm available under license from RSA Data Security Inc. For licensing information, contact: RSA Data Security, Inc. 100 Marine Parkway Redwood City, CA 94065-1031
[7] Eastlake, D., Crocker, S., and J. Schiller, "Randomness Recomnendations for Security", RFC 1750, December 1994.
[8] "The Unicode Standard, Version 2.0", The Unicode Consortium, Addison-Wesley, 1996. ISBN 0-201-48345-9.
[9] "DES Modes of Operation", Federal Information Processing Standards Publication 81, National Institute of Standards and Technology, December 1980
13. Acknowledgements ๐ซถ
Thanks (in no particular order) to Jeff Haag (Jeff_Haag@3com.com), Bill Palter (palter@network-alchemy.com), Bruce Johnson (bjohnson@microsoft.com), Tony Bell (tonybe@microsoft.com), Benoit Martin (ehlija@vircom.com), and Joe Davies (josephd@microsoft.com) for useful suggestions and feedback ๐
14. Chair's Address ๐ท
The PPP Extensions Working Group can be contacted via the current chair:
Karl Fox
Ascend Communications
3518 Riverside Drive
Suite 101
Columbus, OH 43221
Phone: +1 614 326 6841
EMail: karl@ascend.com
15. Authors' Addresses โจ
Questions about this memo can also be directed to:
Glen Zorn
Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052
Phone: +1 425 703 1559
Fax: +1 425 936 7329
EMail: glennz@microsoft.com
Steve Cobb
Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052
EMail: stevec@microsoft.com
Appendix A - Pseudocode ๐ง
The routines mentioned in the text are described in pseudocode below ๐
A.1 LmChallengeResponse()
LmChallengeResponse(
IN 8-octet Challenge,
IN 0-to-14-oem-char Password,
OUT 24-octet Response )
{
LmPasswordHash( Password, giving PasswordHash )
ChallengeResponse( Challenge, PasswordHash, giving Response )
}
A.2 LmPasswordHash()
LmPasswordHash(
IN 0-to-14-oem-char Password,
OUT 16-octet PasswordHash )
{
Set UcasePassword to the uppercased Password
Zero pad UcasePassword to 14 characters
DesHash( 1st 7-octets of UcasePassword,
giving 1st 8-octets of PasswordHash )
DesHash( 2nd 7-octets of UcasePassword,
giving 2nd 8-octets of PasswordHash )
}
A.3 DesHash()
DesHash(
IN 7-octet Clear,
OUT 8-octet Cypher )
{
/*
* Make Cypher an irreversibly encrypted form of Clear by
* encrypting known text using Clear as the secret key.
* The known text consists of the string
*
* KGS!@#$%
*/
Set StdText to "KGS!@#$%"
DesEncrypt( StdText, Clear, giving Cypher )
}
A.4 DesEncrypt()
DesEncrypt(
IN 8-octet Clear,
IN 7-octet Key,
OUT 8-octet Cypher )
{
/*
* Use the DES encryption algorithm [4] in ECB mode [9]
* to encrypt Clear into Cypher such that Cypher can
* only be decrypted back to Clear by providing Key.
* Note that the DES algorithm takes as input a 64-bit
* stream where the 8th, 16th, 24th, etc. bits are
* parity bits ignored by the encrypting algorithm.
* Unless you write your own DES to accept 56-bit input
* without parity, you will need to insert the parity bits
* yourself.
*/
}
A.5 NtChallengeResponse()
NtChallengeResponse(
IN 8-octet Challenge,
IN 0-to-256-unicode-char Password,
OUT 24-octet Response )
{
NtPasswordHash( Password, giving PasswordHash )
ChallengeResponse( Challenge, PasswordHash, giving Response )
}
A.6 NtPasswordHash()
NtPasswordHash(
IN 0-to-256-unicode-char Password,
OUT 16-octet PasswordHash )
{
/*
* Use the MD4 algorithm [5] to irreversibly hash Password
* into PasswordHash. Only the password is hashed without
* including any terminating 0.
*/
}
A.7 ChallengeResponse()
ChallengeResponse(
IN 8-octet Challenge,
IN 16-octet PasswordHash,
OUT 24-octet Response )
{
Set ZPasswordHash to PasswordHash zero-padded to 21 octets
DesEncrypt( Challenge,
1st 7-octets of ZPasswordHash,
giving 1st 8-octets of Response )
DesEncrypt( Challenge,
2nd 7-octets of ZPasswordHash,
giving 2nd 8-octets of Response )
DesEncrypt( Challenge,
3rd 7-octets of ZPasswordHash,
giving 3rd 8-octets of Response )
}
A.8 LmEncryptedPasswordHash()
LmEncryptedPasswordHash(
IN 0-to-14-oem-char Password,
IN 8-octet KeyValue,
OUT 16-octet Cypher )
{
LmPasswordHash( Password, giving PasswordHash )
PasswordHashEncryptedWithBlock( PasswordHash,
KeyValue,
giving Cypher )
}
A.9 PasswordHashEncryptedWithBlock()
PasswordHashEncryptedWithBlock(
IN 16-octet PasswordHash,
IN 8-octet Block,
OUT 16-octet Cypher )
{
DesEncrypt( 1st 8-octets PasswordHash,
1st 7-octets Block,
giving 1st 8-octets Cypher )
DesEncrypt( 2nd 8-octets PasswordHash,
1st 7-octets Block,
giving 2nd 8-octets Cypher )
}
A.10 NtEncryptedPasswordHash()
NtEncryptedPasswordHash( IN 0-to-14-oem-char Password IN 8-octet
Challenge OUT 16-octet Cypher ) {
NtPasswordHash( Password, giving PasswordHash )
PasswordHashEncryptedWithBlock( PasswordHash,
Challenge,
giving Cypher )
}
A.11 NewPasswordEncryptedWithOldNtPasswordHash() ๐
Okay bestie, this one is a combo move โจ It runs NtPasswordHash() on the OldPassword first, then uses that hash to lock up the NewPassword with EncryptPwBlockWithPasswordHash(). Iconic, honestly ๐ฅ
datatype-PWBLOCK
{
256-unicode-char Password
4-octets PasswordLength
}
NewPasswordEncryptedWithOldNtPasswordHash(
IN 0-to-256-unicode-char NewPassword,
IN 0-to-256-unicode-char OldPassword,
OUT datatype-PWBLOCK EncryptedPwBlock )
{
NtPasswordHash( OldPassword, giving PasswordHash )
EncryptPwBlockWithPasswordHash( NewPassword,
PasswordHash,
giving EncryptedPwBlock )
}
A.12 EncryptPwBlockWithPasswordHash() ๐
This is where the password gets wrapped up, and it's giving secret-keeper energy ๐คซ The PWBLOCK gets filled with random octets first, then the password gets tucked into the END of it (right-aligned, babe), its length goes in the PasswordLength field, and then the whole block is RC4 encrypted using the PasswordHash as the key.
EncryptPwBlockWithPasswordHash(
IN 0-to-256-unicode-char Password,
IN 16-octet PasswordHash,
OUT datatype-PWBLOCK PwBlock )
{
Fill ClearPwBlock with random octet values
PwSize = lstrlenW( Password ) * sizeof( unicode-char )
PwOffset = sizeof( ClearPwBlock.Password ) - PwSize
Move PwSize octets to (ClearPwBlock.Password + PwOffset ) from Password
ClearPwBlock.PasswordLength = PwSize
Rc4Encrypt( ClearPwBlock,
sizeof( ClearPwBlock ),
PasswordHash,
sizeof( PasswordHash ),
giving PwBlock )
}
A.13 Rc4Encrypt() ๐ฆ
RC4 time! ๐ง This is the tool doing the actual scrambling. The comment in the original says it all, so here it is, unedited:
Rc4Encrypt(
IN x-octet Clear,
IN integer ClearLength,
IN y-octet Key,
IN integer KeyLength,
OUT x-octet Cypher )
{
/*
* Use the RC4 encryption algorithm [6] to encrypt Clear of
* length ClearLength octets into a Cypher of the same length
* such that the Cypher can only be decrypted back to Clear
* by providing a Key of length KeyLength octets.
*/
}
A.14 OldNtPasswordHashEncryptedWithNewNtPasswordHash() ๐ธ
Ngl the name is a whole mood, but the vibe is simple: hash both passwords with NT, then encrypt the OLD hash using the NEW hash as the block ๐ซถ
OldNtPasswordHashEncryptedWithNewNtPasswordHash(
IN 0-to-256-unicode-char NewPassword,
IN 0-to-256-unicode-char OldPassword,
OUT 16-octet EncryptedPasswordHash )
{
NtPasswordHash( OldPassword, giving OldPasswordHash )
NtPasswordHash( NewPassword, giving NewPasswordHash )
NtPasswordHashEncryptedWithBlock( OldPasswordHash,
NewPasswordHash,
giving EncryptedPasswordHash )
}
A.15 NewPasswordEncryptedWithOldLmPasswordHash() ๐
Same energy as A.11, just with the LM hash doing the heavy lifting this time ๐ It runs LmPasswordHash() on the OldPassword, then uses it to encrypt the NewPassword with EncryptPwBlockWithPasswordHash().
NewPasswordEncryptedWithOldLmPasswordHash(
IN 0-to-256-unicode-char NewPassword,
IN 0-to-256-unicode-char OldPassword,
OUT datatype-PWBLOCK EncryptedPwBlock )
{
LmPasswordHash( OldPassword, giving PasswordHash )
EncryptPwBlockWithPasswordHash( NewPassword, PasswordHash,
giving EncryptedPwBlock )
}
A.16 OldLmPasswordHashEncryptedWithNewNtPasswordHash() ๐
Okay this one mixes both worlds ๐ The OLD password gets the LM hash, the NEW password gets the NT hash, and then the old LM hash is encrypted using the new NT hash as the block. Lowkey clever.
OldLmPasswordHashEncryptedWithNewNtPasswordHash(
IN 0-to-256-unicode-char NewPassword,
IN 0-to-256-unicode-char OldPassword,
OUT 16-octet EncryptedPasswordHash )
{
LmPasswordHash( OldPassword, giving OldPasswordHash )
NtPasswordHash( NewPassword, giving NewPasswordHash )
NtPasswordHashEncryptedWithBlock( OldPasswordHash, NewPasswordHash,
giving EncrytptedPasswordHash )
}
A.17 NtPasswordHashEncryptedWithBlock() ๐ฆ
This is the DES step, and it's a two-for-one ๐ฏโโ๏ธ The 16-octet PasswordHash gets split in half, and each 8-octet half gets DES encrypted with the matching 7-octet piece of the Block.
NtPasswordHashEncryptedWithBlock(
IN 16-octet PasswordHash,
IN 16-octet Block,
OUT 16-octet Cypher )
{
DesEncrypt( 1st 8-octets PasswordHash,
1st 7-octets Block,
giving 1st 8-octets Cypher )
DesEncrypt( 2nd 8-octets PasswordHash,
2nd 7-octets Block,
giving 2nd 8-octets Cypher )
}
Appendix B - Examples ๐
B.1 Negotiation Examples ๐ฆ
Here are some examples of typical negotiations, bestie ๐ The peer is on the left and the authenticator is on the right.
The packet sequence ID gets incremented on each authentication retry Response and on the change password response. Every case where the packet sequence ID gets updated is noted below ๐
Response retry is never allowed after Change Password. Change Password may occur after Response retry. The implied challenge form is shown in the examples, though all cases of first challenge+23 should be replaced by the C=cccccccccccccccc challenge if authenticator supplies it in the Failure packet. Read that last part twice, it matters ๐
B.1.1 Successful authentication โจ
<- Challenge
Response ->
<- Success
B.1.2 Failed authentication with no retry allowed ๐
<- Challenge
Response ->
<- Failure (E=691 R=0)
B.1.3 Successful authentication after retry ๐
<- Challenge
Response ->
<- Failure (E=691 R=1), disable short timeout
Response (++ID) to first challenge+23 ->
<- Success
B.1.4 Failed hack attack with 3 attempts allowed ๐
<- Challenge
Response ->
<- Failure (E=691 R=1), disable short timeout
Response (++ID) to first challenge+23 ->
<- Failure (E=691 R=1), disable short timeout
Response (++ID) to first challenge+23+23 ->
<- Failure (E=691 R=0)
B.1.5 Successful authentication with password change ๐
<- Challenge
Response ->
<- Failure (E=648 R=0 V=2), disable short timeout
ChangePassword (++ID) to first challenge ->
<- Success
B.1.6 Successful authentication with retry and password change ๐
<- Challenge
Response ->
<- Failure (E=691 R=1), disable short timeout
Response (++ID) to first challenge+23 ->
<- Failure (E=648 R=0 V=2), disable short timeout
ChangePassword (++ID) to first challenge+23 ->
<- Success
B.2 Hash Example ๐งช
Here are the intermediate values for the password "MyPw" ๐
8-octet Challenge:
10 2D B5 DF 08 5D 30 41
0-to-256-unicode-char NtPassword:
4D 00 79 00 50 00 77 00
16-octet NtPasswordHash:
FC 15 6A F7 ED CD 6C 0E DD E3 33 7D 42 7F 4E AC
24-octet NtChallengeResponse:
4E 9D 3C 8F 9C FD 38 5D 5B F4 D3 24 67 91 95 6C
A4 C3 51 AB 40 9A 3D 61
B.3 Example of DES Key Generation ๐
DES uses 56-bit keys, which get expanded to 64 bits by inserting parity bits. Once the key's parity is fixed, every eighth bit is a parity bit, and the number of bits set (1) in each octet is odd, aka odd parity. Heads up: lots of DES engines don't check parity at all and just strip the parity bits out ๐
This example shows the values that come out when you use the 16-octet NTPasswordHash from Appendix B.2 to generate a pair of DES keys (for example, for use in the NtPasswordHashEncryptedWithBlock() described in Appendix A.17) ๐ง
16-octet NtPasswordHash:
FC 15 6A F7 ED CD 6C 0E DD E3 33 7D 42 7F 4E AC
First "raw" DES key (initial 7 octets of password hash):
FC 15 6A F7 ED CD 6C
First parity-corrected DES key (eight octets):
FD 0B 5B 5E 7F 6E 34 D9
Second "raw" DES key (second 7 octets of password hash)
0E DD E3 33 7D 42 7F
Second parity-corrected DES key (eight octets):
0E 6E 79 67 37 EA 08 FE
Full Copyright Statement ๐
Okay, the legal bit. Please read it, it's important, and I'm keeping every word exactly as it is ๐ซถ
Copyright (C) The Internet Society (1998). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
๐ฆ where this page comes from
- ietf: rfc2433 1998-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms