aspose file tools*
The moose likes Java in General and the fly likes encrypting passwords Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "encrypting passwords" Watch "encrypting passwords" New topic
Author

encrypting passwords

Dean Fredericks
Ranch Hand

Joined: Dec 04, 2004
Posts: 60
Hi guys

Does anybody body know a simple way to encrypt a password so its not readable by humans?

Im hoping somebody will tell me there is a class in J2SE I can use, or a simple free library out there, or any other simple method I can use.

Thanks cheers


PLEASE WATCH THIS VIDEO: <a href="http://www.glumbert.com/media/dolphin" target="_blank" rel="nofollow">http://www.glumbert.com/media/dolphin</a><br /> <br /><-- that video is no joke. Spread the word... this cant go on!!!<br /> <br />SCJP 1.4, SCBCD 1.3, SCWCD 1.4, SCMAD 1.0
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14156
    
  19

One method to encrypt passwords is to use a one way algorithm, for example a hash code algorithm like MD5 or SHA.

You calculate the MD5 or SHA hashcode and store that in the database. If you want to verify if a user entered the password correctly, you calculate the hashcode of the text that the user entered and compare that with the hashcode in the database.

Note that those hashcode algorithms are one way: there's no way to compute the actual password if you only have the hashcode.

You can calculate those hashcodes using class java.security.MessageDigest (lookup the API documentation).
[ October 11, 2005: Message edited by: Jesper de Jong ]

Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Dean Fredericks
Ranch Hand

Joined: Dec 04, 2004
Posts: 60
Hey, thanks for the reply.

If i am to use MD5 of SHA, what are the code steps i need to do? Looking at the java libraries I see input streams output streams, and some mention also about needing to get a 3rd party library which implements the abstract classes in the standard J2SE.

Whats going on?
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14156
    
  19

It's very simple: Create a MessageDigest object using the getInstance() factory method, update it with the password and get the digest as a byte array.
Bill Goldsworthy
Greenhorn

Joined: Dec 21, 2004
Posts: 27
I've found this to work well:

http://www.twmacinta.com/myjava/fast_md5.php


Increasingly, people seem to misinterpret complexity as sophistication, which is baffling - the incomprehensible should cause suspicion rather than admiration. Possibly this trend results from a mistaken belief that using a somewhat mysterious device confers an aura of power on the user. Niklaus Wirth
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14156
    
  19

Originally posted by Bill Goldsworthy:
I've found this to work well:

http://www.twmacinta.com/myjava/fast_md5.php


Nice, but calculating MD5 digests is already built-in in the Java standard library, and if you're only calculating the digests of very short strings like passwords, you don't need a special fast implementation of the MD5 algorithm. The less extra libraries you include in your project, the better...
Dean Fredericks
Ranch Hand

Joined: Dec 04, 2004
Posts: 60
In the code example, it seems you dont generate a key ???
surley you need a key?
why isnt there one?

Thanks
Dean
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14156
    
  19

No, you don't need a key. Calculating a digest from some data is not the same as encryption using public and private keys.

Did you understand how this is supposed to work?

When you create a new account for a user, you give the user a password. In your username / password table in the database, you do not store the password itself, but the digested form of the password.

When the user logs in into the application, (s)he enters the password. The application digests what the user has entered and compares that digest to the digest in the database. When the digests are equal, the user has entered the correct password.

People who have access to the database can see the digested passwords of the users in the username / password table. That's no security problem, because it's not possible to compute the password if you only have the digest, and you can't login into the application if you only have the digest.

The algorithm used to calculate the digest is like a valve: it only works in one direction. You can compute the digest from the password, but you can't compute the password from the digest.

You don't need an encryption system with public and private keys for this application.

By the way, this is exactly how passwords are stored in most versions of Unix. If you're using a Unix computer, try looking at the content of the file /etc/passwd. You'll see that it does not contain the passwords of the users - it contains some strange strings, which are the digested form of the passwords.
[ October 12, 2005: Message edited by: Jesper de Jong ]
Akshay Sri
Greenhorn

Joined: Apr 22, 2003
Posts: 7
message digests are sufficient for most simple applications. I have used them myself for encrypting passwords. The flip side is you cannot 'decrypt' a digest to get the original password. The way they work is that a given password string will *always* yeild the same message digest string. Here is some code you can use for this purpose. This always gives a 32 byte MD5 hash of the passed in String(password). Note that you will need to *always* compare the digest of the passwords for authentication.

public String getHash(String inputString) throws EncryptionException
{
String hashCode = null;
MessageDigest msd = MessageDigest.getInstance("MD5", "SUN");
BigInteger bInt= null;
StringBuffer stBuf = null;
try{
// msd.digest() calculates the hash and returns a byte array.
// The byte array is then converted into String equivalent and returned
// 1 stands for + sign
// The byte array is taken to be in big-endian byte-order:
// the most significant byte is in the zeroth element.
bInt = new BigInteger( 1, msd.digest(inputString.getBytes()) );
stBuf = new StringBuffer(bInt.toString( 16 ));

}catch(NumberFormatException nfe){
///log
}

//Packing the left side of the resultant String with 0s if it is
//not equal to 32 chars.
int lt = stBuf.length();
for(int len = 0; len <32-lt;len++) {
stBuf.insert(0,'0');
}
hashCode = stBuf.toString();
return hashCode;
}

However, if you are keen on a key based cipher encryption algorithm. Then a simple way is to use a secret key algorithm (eg Blowfish). Here there is only ONE key used for both encryption and decryption. Here is some example code you can use. Note this code generates a key first then uses it to encrypt some string then decrypts it. However, you will need to generate the secret key ONLY once, then store it in some secure place and thereafter read the key first & then use it to encrypt/decrypt. To run this u need jvm 1.4 and need to configure the SUN JCE security provider:

KeyGenerator kg = null;

try {
kg = KeyGenerator.getInstance("Blowfish","SunJCE");


} catch (NoSuchAlgorithmException e) {
e.printStackTrace();

} catch (NoSuchProviderException e) {
e.printStackTrace();

}
kg.init(128);
SecretKey sk = kg.generateKey();
Cipher ci = null;
try {
ci = Cipher.getInstance("Blowfish");

} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
try {
ci.init(Cipher.ENCRYPT_MODE,sk);

} catch (InvalidKeyException e) {
e.printStackTrace();
}

//Encrypting
String st = "SomeString";
byte[] inputBytes = null;

try {
inputBytes = st.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
byte [] encryptedBytes = null;
try {
encryptedBytes = ci.doFinal(inputBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
String encryptedData = null;
try {
encryptedData = new String(encryptedBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("encrypted string "+encryptedData);

//Decrypting
try {
ci.init(Cipher.DECRYPT_MODE,sk);
} catch (InvalidKeyException e) {
e.printStackTrace();
}

byte [] decryptedBytes = null;
try {
decryptedBytes = ci.doFinal(encryptedBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
String decryptedData = null;
try {
decryptedData = new String(decryptedBytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("decrypted string "+decryptedData);
David O'Meara
Rancher

Joined: Mar 06, 2001
Posts: 13459

"Akshay xyz",
Hey, welcome back!

Unfortunately your display name is not valid.

We require display names to be two words: your first name, a space, then your last name. Fictitious names are not allowed. You can find a previous warning here.

Please edit your profile and correct your display name, since accounts with invalid display names get deleted.

thanks,
Dave
 
 
subject: encrypting passwords