A word you use to prove that you are truly you to a computer. You will have
a password to log on to your operating system, one for each affiliate, and even
one for various free services on the web. Snoops can look at your files without
knowing your login password by booting with an Ubuntu Linux
CD and examining your files, bypassing Windows and its passwords. To protect
against that, you need to encrypt your files. Then you have passwords on your
files, not just Windows as a whole.
Selecting Passwords
Passwords that are easy to guess include the names of loved ones and relatives,
words in the dictionary, especially ones with strong emotional connotation like
God, whale, love.
A tool can crack your password just by trying all words in the dictionary. So
you must disguise them. Add digits, mix the case. This little program will
generate you an impossible to guess password. If want to make sure I am not
keeping a copy, download the
source, check the program out, and run it on your own machine.
If the print is too small to see, use the Opera browser
and zoom. Or copy/paste the generated password blind.
Implementing Passwords
In a highly secure system, each end has a public and private key. They each
encrypt and digitally sign a random message for the other to establish identity.
Even these have to be carefully designed to withstand a man-in-the-middle attack.
There are some lower tech alternatives:
- If you have Java on both ends, the server could send a random string of bytes to
the client. The client could concatenate that with a string of bytes
representing the password, then run it through a SHA-1 or MD-5 digest and send
it back to the server. The server does the same thing and compares its version
with the client’s.
- If the server is C++ it won’t necessarily have access to a SHA-1 or MD-5
digest. You could then have to come up with a digest
function you can implement easily in C++. You could use an Adler or CRC with
some wrinkle to make it a tad harder to crack, or use one of the HashCode
algorithms.
- If you want to avoid a two way exchange for faster login, let the random key be
the time of day stamp in UTC. The client sends it along in plaintext with the
digest. The timestamp is rejected if it is too far from "now".
- For something even lower tech, but unfortunately easy to crack, try XORing the
bytes of the password with something you change periodically.
- Base64 alone, cascaded Base64 or ROT13 is no protection at all.
Digest Passwords
Servers often don’t store bald passwords. They store some sort of digest
of them. That way if someone cracks the password file, they still don’t
know the passwords.
Typically raw binary bytes generated by such authentication
schemes are exchanged in base64.
Tomcat has a single signon so that all applications in a realm share the same
set of user-ids and passwords. If a user logs in to one application, he is
logged in to all. This scheme uses cookies to authenticate each request.
Tomcat lets you configure the tables and columns to
automatically look up and validate passwords. Caucho Resin
similarly lets you configure SQL queries to automatically find the passwords in
your database.
Graphical Passwords
Another way is to use graphical passwords, easier for the user to remember, and
harder to steal. The basic idea is you display a complex image to the user and
he selects a number of click
points. I suspect this scheme is much less secure than it creators claim,
since there are a limited number of natural points of interest in a photo, which
could be easily discovered by showing the photo to 100 people.
Passwords at the Client
When your Applet or JWS applications is pretending
to be a browser talking to a server, you can use the java.net.Authenticator
to automatically insert the userid and password base64-encoded in your HTTP
headers in the Authorization field. If the server does
not like you userid/password combination in return a 401
Unauthorized response code. The server gives you no hint as to whether
the userid or the password is the problem. You might consider this obnoxious
behaviour, but it is done that way to make life difficult for people trying to
hack the system.
Passwords at the Server
How passwords are handled is specific to each application server. Most will
provide a rudimentary, unsuitable-for-production flat file scheme. The better
ones will provide a means of configuring a database for the users. Almost all
allow you to extend a class to provide a custom source.
Java Servlets defines a simple password scheme controlled entirely by a flat
file web.xml. This would be suitable for a small
company where the list of users and passwords could be maintained with a text
editor by the system administrator.
The best approach (for expandability) is to incorporate a third party SSO (single
sign-on) (some application servers come with one). This allows you
to add new applications and share the login across them with a minimum of effort.
Also, they typically plug into an existing LDAP taking
user and password management out of the application’s hands. This allows
corporations to take advantage of existing LDAP data when deploying applications.
Tomcat offers five different interfaces to databases of passwords. JDBCRealm
lets you interface to a SQL users and userroles
tables. You configure the name of your table containing the user ids and
passwords (among other things) and your roles table which describes which roles
a user can play. You assign Tomcat a userid/password and jDBC connect string to
give it with read-only access to your database to perform the authentications.
It is much simpler than it first looks.
Puzzles
Things I have not yet figured out include:
- How do you arrange for a timeout, so that after a period of inactivity, the
login expires an the user has to re-enter his password. I know how to do it from
first principles, but not with Tomcat.
- Just how much does the Applet get in involved with cookies, or do they get
piggybacked behind its back.
- Does Java Authenticator understand the Tomcat cookie scheme?