Code Comments
Programming Forum and web based access to our favorite programming groups.Hi everybody, I would like to implement an authentication scheme that is used in PHP websites all the time, but I can't seem to figure out how to make a Java equivelant. The PHP code is really simple: / Get the two character salt from the username $salt = substr($loginName, 0, 2); // Encrypt the password $crypted_password = crypt($loginPassword, $salt); // Formulate the SQL query to find the user $query = "SELECT password FROM customers WHERE email = '$loginName' AND password = '$crypted_password'"; // Execute the query $result = @ mysql_query ($query, $connection) or showerror(); // exactly one row? then we have found the user if (mysql_num_rows($result) != 1 || $already_logged===true) return false; else return true; As you can see, nothing shocking is happening there. A password is encrypted using a salt (first two letters of the login name). It is then checked whether this password is in the database for the user that is trying to log in. This has the advantage that the password is stored in the database in encrypted form meaning that even if the database is comprimized the users passwords are still safe. In other words, what I'm looking for is an encryption method that simply encrypts using a salt (and thus produces the same encrypted_string every time given a certain password/salt combination). No decryption is ever needed. However, all the examples on encryption that I find on the Net are all regarding public and secret keys and make things way too complicated for my humble needs. Does anybody have a simple example on how to do this in Java or know of a URL where such an example is posted? Any help is much appreciated, thanks, Jonck
Post Follow-up to this messageThis is really a digest/hash (not encryption). You could get similar
results doing:
String username = "user";
String password = "pass";
public String hash(String username, String password) throws Exception {
MessageDigest digest = MessageDigest.getInstance("SHA1");
byte[] bytes = (username + password).getBytes("UTF-8");
byte[] hash = digest.doFinal(bytes);
// now hex-encode the hash to get a nice string
StringBuffer s = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
s.append(Integer.toHexString((hash[i] >> 4) & 0x0f));
s.append(Integer.toHexString(hash[i] & 0x0f));
}
return s.toString();
}
While salting the password as above (i.e. with a portion/all of the
username) does reduce the possibility of a dictionary attack, it's still
possible to get a collision (i.e., user "cowb" with password "oys" and
user "cow" with password "boys" would have the same hash). You could
diffuse this a bit by using a MAC with the username as the key.
Jonck van der Kogel wrote:
> Hi everybody,
> I would like to implement an authentication scheme that is used in PHP
> websites all the time, but I can't seem to figure out how to make a
> Java equivelant.
> The PHP code is really simple:
>
> / Get the two character salt from the username
> $salt = substr($loginName, 0, 2);
>
> // Encrypt the password
> $crypted_password = crypt($loginPassword, $salt);
>
> // Formulate the SQL query to find the user
> $query = "SELECT password FROM customers
> WHERE email = '$loginName'
> AND password = '$crypted_password'";
>
> // Execute the query
> $result = @ mysql_query ($query,
> $connection)
> or showerror();
>
> // exactly one row? then we have found the user
> if (mysql_num_rows($result) != 1 || $already_logged===true)
> return false;
> else
> return true;
>
> As you can see, nothing shocking is happening there. A password is
> encrypted using a salt (first two letters of the login name). It is
> then checked whether this password is in the database for the user
> that is trying to log in. This has the advantage that the password is
> stored in the database in encrypted form meaning that even if the
> database is comprimized the users passwords are still safe.
>
> In other words, what I'm looking for is an encryption method that
> simply encrypts using a salt (and thus produces the same
> encrypted_string every time given a certain password/salt
> combination). No decryption is ever needed. However, all the examples
> on encryption that I find on the Net are all regarding public and
> secret keys and make things way too complicated for my humble needs.
>
> Does anybody have a simple example on how to do this in Java or know
> of a URL where such an example is posted?
>
> Any help is much appreciated, thanks, Jonck
Post Follow-up to this messagenobody wrote:
> This is really a digest/hash (not encryption). You could get similar
> results doing:
>
> String username = "user";
> String password = "pass";
>
> public String hash(String username, String password) throws Exception
3;
> MessageDigest digest = MessageDigest.getInstance("SHA1");
> byte[] bytes = (username + password).getBytes("UTF-8");
> byte[] hash = digest.doFinal(bytes);
> // now hex-encode the hash to get a nice string
> StringBuffer s = new StringBuffer();
> for (int i = 0; i < hash.length; i++) {
> s.append(Integer.toHexString((hash[i] >> 4) & 0x0f));
> s.append(Integer.toHexString(hash[i] & 0x0f));
> }
Note that this generates one String object per hex digit. While
that's fine in many environments, if the OP is getting many logins, GC
can be held down by reducing the number of ephemeral objects, e.g.
char[] hexed=new char[hash.length*2];
for (int jj=0, kk=0; jj<hash.length; ++jj) {
hexed[kk++]="0123456789ABCDEF".charAt((hash[jj]>>4) & 0x0F);
hexed[kk++]="0123456789ABCDEF".charAt(hash[jj] & 0x0F);
}
return new String(hexed);
> return s.toString();
> }
>
> While salting the password as above (i.e. with a portion/all of the
> username) does reduce the possibility of a dictionary attack, it's still
> possible to get a collision (i.e., user "cowb" with password "oys" and
> user "cow" with password "boys" would have the same hash). You could
> diffuse this a bit by using a MAC with the username as the key.
Typically a collision is made impossible interposing a character that
is not legal in the username, such as
byte[] bytes=(username+':'+password).getBytes("UTF-8");
--Mike Amling
Post Follow-up to this messageThanks very much for your responses guys, this is just what I was looking fo
r!
Thanks again, Jonck
Michael Amling <nospam@nospam.com> wrote in message news:<NZ84c.33241$PY.29579@newssvr26.ne
ws.prodigy.com>...
> nobody wrote:
>
> Note that this generates one String object per hex digit. While
> that's fine in many environments, if the OP is getting many logins, GC
> can be held down by reducing the number of ephemeral objects, e.g.
> char[] hexed=new char[hash.length*2];
> for (int jj=0, kk=0; jj<hash.length; ++jj) {
> hexed[kk++]="0123456789ABCDEF".charAt((hash[jj]>>4) & 0x0
F);
> hexed[kk++]="0123456789ABCDEF".charAt(hash[jj] & 0x0F);
> }
> return new String(hexed);
>
>
>
> Typically a collision is made impossible interposing a character that
> is not legal in the username, such as
> byte[] bytes=(username+':'+password).getBytes("UTF-8");
>
> --Mike Amling
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.