This week's book giveaway is in the Agile and other Processes forum. We're giving away four copies of The Mikado Method and have Ola Ellnestam and Daniel Brolund on-line! See this thread for details.
I'm using an open source web application (Moodle), which is mostly using PHP. My Java question; What is the best method to encrypt passwords using Java, that will also be compatible with PHP?
IOW: password = EncryptData(password);
Marcus Green
arch rival
Rancher
Joined: Sep 14, 1999
Posts: 2813
posted
0
Moodle stores passwords in a hashed format, i.e. so you can compare passwords but not decrypt them. If you want to modify Moodle you are probably better off doing it in PHP as then it fits in nicely with everything else. PHP is quite easy to learn and use, and there's no shame in using it it if you (like me) are a serious Java type person.
(Last year I went to visit the creator of Moodle Martin Dougiamas in Perth Western Australia, he is a very, very cool guy).
My java program is reading data from a M$ SQL data. This contains user info that is being inserted into the Moodle users table, and contains their passwd in clear text. I need to insert it encrypted. Here is the code: /* its ok to criticize the code, even welcome, */
/* Program Name: Moodletest: Description: Move Zangle data into Moodle Database. Author: Michael Anderson Date: 10/18/2007 ============================================================================== Author: Michael Anderson (Writing COBOL for 1/4 century) */ import javax.sql.*; import java.io.*; import java.net.*; import java.sql.*; import java.lang.*; import java.text.*; import java.util.Date; public class Moodletest { public static java.sql.Connection zcon = null; public static java.sql.Connection mcon = null; public static String url = null; public static String serverName = null; public static String portNumber = null; public static String databaseName = null; public static String userName = null; public static String password = null; public static String selectMethod = null;
public Moodletest() { String zquery = "select distinct * from Moodle_Users where username > ''"; Statement zstmt; StringBuffer mquery = new StringBuffer(" ");
for (int i = 1; i <= numberOfColumns; i++) { if (i > 1) System.out.print(", "); String columnName = zrsmd.getColumnName(i); System.out.print(columnName); } System.out.println("");
Date now = new Date(); System.out.println(now.toString()); System.out.println(sqlExa.toString()); System.out.println(mquery.toString()); System.out.println(" \n"); // System.exit(0); }
If you are OK to use hashing, you could make use of a hashing algorithm like SHA1 or MD5. Both are supported by Java, PHP and even MySQL. Only problem is, these algorithms are one-way hashing algorithms. You cannot retrieve the password back from it. One thing you can do is compare the hashes, instead of passwords.
And for PHP, you could make use of the functions sha1() and md5().
MySQL also has built-in functions which can be used to generate hashes. They are SHA1(), SHA() and MD5().
If its really necessary for you to retrieve the password, you may consider using an encoding algorithm like Base64. PHP natively supports it through base64_encode() and base64_decode(). For Java, you will have to use a freely available Base64 Implementation(Just Google for it). [ October 20, 2007: Message edited by: Yohan Liyanage ]
If its really necessary for you to retrieve the password, you may consider using an encoding algorithm like Base64. PHP natively supports it through base64_encode() and base64_decode(). For Java, you will have to use a freely available Base64 Implementation(Just Google for it).
Actually no. Base64 is *not* an encyption algorithm. You might as well use a rot13 on the password, it probably just as easy to break...
If you want to encrypt the password, and later be able to retrieve the password, you need to actually encrypt it. Take a look at the javax.crypto.Cipher class -- which supports a large set of encryption and decryption algorithms.
If you want to encrypt the password, and later be able to retrieve the password, you need to actually encrypt it. Take a look at the javax.crypto.Cipher class -- which supports a large set of encryption and decryption algorithms.
I have never, in over 30 years of programming, needed to retrieve the password. Just tell the user "you can't retrieve it, but will gladly reset it to xyzzy". Then use a HMAC
If you do try to use any of the real ciphers (I'd use AES) then you have a significant problem with how to you protect the key used for the cipher. If you hard code it into your Java source, then anyone with access to the source has the key. If you keep it in a file/property on the disk, anyone with access to the disk has access to the key.
Its a non-trivial problem, and all solutions have serious security or sysadmin risks.
I have never, in over 30 years of programming, needed to retrieve the password. Just tell the user "you can't retrieve it, but will gladly reset it to xyzzy". Then use a HMAC
Unfortunately, in my case, I can't say never. I would say that I have encountered the need, in about a handful of times.
While it sounds good to never have to retrieve the password, you don't get to code the password server all the time -- sometimes your program is a client to another system. Nor can you expect your users to have a single sign on facility. If you have to hold passwords on behalf of your users, so that you can access external services -- your program will be challenged for the password, not for a hash.
And what if you have to store passwords which you use? For example, the admin password to the client database? Your program can't depend on the DBA, everytime that it is restarted -- nor would he/she appreciate your program storing it in the clear.
If you hard code it into your Java source, then anyone with access to the source has the key. If you keep it in a file/property on the disk, anyone with access to the disk has access to the key.
Its a non-trivial problem, and all solutions have serious security or sysadmin risks.
I think of it like this. The goal is not to find a solution that is 100 percent perfect. The goal is to find a solution that is more secure than everything around it.
For example, if the local datastore (on the client) is not secure, then don't have the client challenge for the password -- have all the password challenges on the server, and have the client use a token (from the server), once it users passes the challenge. This way, the server can store it in the local datastore, which can be more secure.
Of course, someone with the admin password on the server now has access to the user passwords. But quite frankly, if someone that you don't trust has admin access to your server, you have way more problems than one program/service.
A good analogy to this is... If you encounter a hungry bear in the forest, you don't have to outrun the bear. You just have to outrun the person next to you...
Henry [ October 20, 2007: Message edited by: Henry Wong ]