Safe The Login
In Assignment
2, our simple message protocol uses a plain text login: the
userid and password are sent on an unencrypted IP connection, which
can be easily snooped. An more secure alternative is to use a hashing
challenge, with a cryptographic hash function. A crypto hashing function
maps data of arbitrary length to an apparently random string of bits.
The bits are not actually random, since they are the value of a function,
but they appear so. A good one should have these properties:
- There is no known efficient way to invert the function.
That generally means the only way to find a string that produces a
particular value is by guessing until one is found, a prohibitively slow
process.
- A small change to the data should make a large change to the hash value,
so similar hashes will not be produced by similar data.
- Collisions are rare and unpredictable.
There are a number of well-studied hashing functions which have open
standards. We will use the sha256, which is standardized by the US NIST.
The use
here is to let the client show the server that it knows the
correct password without ever needing to transmit it. The process is:
- The server sends a large random string, known as a challenge, to the
client.
- The client appends the challenge to the password, computes the
hash of the resulting string, and sends it back to the server.
This is the response to the challenge.
- The server also knows the challenge (it sent it) and the password,
so it can compute the hash. If it matches the hash sent by the client,
the login is successful
- A new challenge is used for every login attempt, so challenges
are extremely unlikely to be repeated over any reasonable time frame.
Since hash functions are not practically reversible, intercepting the
response does not reveal the password. Since the challenge always changes,
the response cannot be repeated to accomplish a login.
The current server
on Sandbox has been upgraded to version 0.1.3,
implementing protocol version 1.1. It now provides two additional
commands:
CHL
The client requests a login challenge, which just a string of randomly-chosen
characters. On success, the response is two lines,
S 109 Challenge follows, then a single line containing a string
of random characters in the set a-zA-Z+/.
(There is no specific failure response for this command, though E 120 is
always possible.)
CRS user response
This is a request to log in the indicated user. The response is the
base-64 encoding of the sha256 hash of the concatenation of the
challenge, the userid and the password. If this is correct, the
server will log in the user and respond with S 109. If not,
E 107.
The CHL command associates the challenge with the current connection.
A new connection does not have one.
When CRS is run, it fails if the connection does not have an associated
challenge, then clears that challenge after using it to process
the CRS.
The project is to
modify either your own version of assignment 2, or the posted key,
to log in with the new, more secure challenge authentication.
The user need not see any difference. The client will read the user id
and password, as usual, then run CHL to get a challenge. It will read
the challenge and compute the response by taking the sha256 hash of
the concatenation of the challenge, the user id, and the typed password.
It will then attempt to log in using the CRS command, sending the
userid and the response. The response is binary data, so it must be
coded as text for transmission. As noted above, the server expects this
to be done using the base-64 coding scheme developed for MIME. You are
provided with a sha256
encoder class which will perform those
calculations for you. Please do not try to add this code to your main
file; use #include to bring in the header, and link the files
together at compile time. In an IDE, you may need to create a project
and add the files to it.
If CRS responds with E 107, request the user and password again,
and repeat.
But don't throw away your IAM login code. If the server responds with
E 100 to either CHL or CHS, attempt a login with IAM. This allows your
client to fall back to the old protocol for an older server.
An old server will not recognize the new commands, so sends back the 100
error.
Do not fall back to IAM for an E 107 code. That means that the server
understood the login attempt, but the credentials are wrong. Do not use IAM
under any other circumstances than an E 100 from one of the new commands.
If you like, you
might just start with an extra CHL, and branch to the old code on an E 100
response, then run the new code otherwise.
The new version of the server still supports IAM requests,
but its response says the command is “deprecated”. This language
is used by real services (and other things) when a feature is
to be removed soon, but keep around to allow other parties some time
to adapt.
Thus, an old client should
work with a new server, and the new client should still work with the old
server. This sort of arrangement is common when a protocol is updated.
Submission
When your program is working, nicely commented and properly indented,
submit it using the form
here.