Hello, I have developed a site for our intranet. To begin, the user must type in his username and password. At the moment, the password is stored as clear text in the database. For obvious reasons, we need to change the passwords to be encrypted. I have been doing some research in the Java Cryptography package and have some questions: 1) I am using WebSphere Studio 3.5.4 and VisualAge for Java Advanced Edition version 3.5.3. When I click Help -- About VAJ, it says it is using JDK 1.2.2. How do I use the cryptography package with this tool? From what I've read, the cryptography package is included with v 1.4 but not with previous versions. How do I get the cryptography package to work with VAJ? 2) Are there any tutorials available with a working example included for cryptography? I have tried reading through some of the documentation I've found, but it is very difficult to make progress. I learn best by example, so if anyone has an example of using cryptography to encrypt passwords and perform form validation with the encrypted password in the database, I'd really appreciate your help. 3) Now I'm wondering if the java cryptography package is my best solution. I just need to encrypt one value -- the password. Is there perhaps a better implementation of security for this purpose than the java cryptography? 4) Could anyone provide a brief overview of how the cryptography package works? I'm looking for a nuts-and-bolts tutorial, but before I begin there I'd like to read a high-level overview of how this package works. 5) One last thing: how secure is the cryptography package? If I implement this solution, how confident can I be that the site will be secure? Thanks for your help!
Originally posted by verduka fox: I have been doing some research in the Java Cryptography package
So have I. I had to. I wrote the security and cryptography chapters of this book
1) I am using WebSphere Studio 3.5.4 and VisualAge for Java Advanced Edition version 3.5.3. When I click Help -- About VAJ, it says it is using JDK 1.2.2. How do I use the cryptography package with this tool? [...] How do I get the cryptography package to work with VAJ?
For earlier versions of J2SE, you can download JCE 1.2.1 from the Sun JCE pages. Just install it as a system extension and you should be able to use it from within VAJ or any other tool. I cannot advise you on any specific support VAJ may have.
2) Are there any tutorials available with a working example included for cryptography?
JCE itself comes with pretty decent documentation and some samples. If there's any problem, post to the "Other Java APIs" forum and/or drop me a mail and I'll try to help. Initial comments - for best security, don't encrypt passwords. After all, you'll have to store the decryption keys somewhere and a hacker may break into the system and steal them. Hash them instead. A hash (or message digest) is a one-way transformation - it is very difficult to find a password corresponding to a given cryptographically secure hash. To compare a password, you calculate its hash and compare that to the stored hash. The disadvantage is that you cannot offer password reminder facilities. Usually, some random information (the "salt") is added to the password before calculating the hash. The salt is then stored together with the password. This is more secure because passwords by themselves tend to be not very random.
3) Now I'm wondering if the java cryptography package is my best solution. I just need to encrypt one value -- the password. Is there perhaps a better implementation of security for this purpose than the java cryptography?
Be wary, very wary of implementations you do yourself or that you find somewhere on the 'net. It is very easy to create insecure encryption implementations and very difficult to create secure ones. If you decided that a hash will do the job, you're in luck - J2SE (1.2 and above) contains support for both MD5 and SHA-1 message digests in the core java.security.* API. You won't have to bother with JCE.
4) Could anyone provide a brief overview of how the cryptography package works? I'm looking for a nuts-and-bolts tutorial, but before I begin there I'd like to read a high-level overview of how this package works.
The entire JCA (Java Cryptography Architecture) is based on "providers". There are abstract classes representing most things you'd want to use - key factories, message digests, ciphers, etc. These classes have static factory methods (getInstance()) and sometimes initialisation methods (init()). First, you call a factory method with the name of the implementation you need. For instance, to retrieve a message digest that uses the SHA algorithm:The JCA then goes through the registered providers trying to find one that supplies SHA message digests. Second, you initialise the object, if appropriate. Message digests don't need any initialisation, but a cipher, for instance, would need to be initialised with the encryption mode and the key before you could use it. Finally, you use the object. Unfortunately, this is not the place to describe the various classes in JCA and JCE; that would require a potted introduction to cryptography and the discussion of an API that can initially be quite daunting. But once you know exactly what you want to do I'm happy to provide a more focused discussion. You may want to read Sun's crypto spec for a discussion of message digests (it's also in your JDK documentation).
5) One last thing: how secure is the cryptography package? If I implement this solution, how confident can I be that the site will be secure?
JCA and JCE use first rate implementations of widely accepted, secure cryptographic algorithms (alright, DES has been cracked, but you can use Triple-DES). If you want algorithms not provided by Sun, you can use another provider such as Cryptix. But algorithms are just one side of the picture. Often an application turns out to be as (in)secure as the cryptography skills of the person writing it. Decide first and foremost whether you want to go for a hash or encryption. Once that's fixed we can go into the details if you want - Peter [This message has been edited by Peter den Haan (edited October 31, 2001).]
Joined: Jan 18, 2001
Peter, Thank you so much for your detailed response. After reading it over, I have concluded that since I am only required to encrypt the password, I can use a hash.
If you decided that a hash will do the job, you're in luck - J2SE (1.2 and above) contains support for both MD5 and SHA-1 message digests in the core java.security.* API. You won't have to bother with JCE.
Ok, so now that I'm off the JCE track, where do I find documentation and examples of java.security.*? I looked through the API and believe the class I need to implement is java.security.MessageDigestSpi. Therefore, I'm looking at its subclass java.security.MessageDigest. Can you provide me with any examples or tutorials on doing so?
Do like this: 1)String pass=request.getParameter(Password); 2)int pass=pass.hashCode(); and convert this int to string and save it in database.
Joined: Jan 18, 2001
Pranit, Will the same word always return the same hashCode?
Peter den Haan
Joined: Apr 20, 2000
Originally posted by Pranit Saha: 2)int pass=pass.hashCode();
Whoa! That's not a cryptographically secure hash. Avoid.You then save hash and salt in a database (or wherever). When it comes to comparing a given password with the stored one, you read both salt and hash that had been stored in database and:If match is true, the password has been validated. The SHA-1 hash should be 160 bit, the salt is (in this example) 96 bit; you can either store them separately, or concatenate them and store them in a 32-byte binary database field. An attacker downloading your password table will have a fun time cracking the passwords, as it is not possible to take a cryptographically secure hash such as SHA and derive the password behind it. The worst that can happen is that the attacker reverse engineers the code above, then tries to find passwords using either an exhaustive search (which is why you should ideally require a minimum password length) or a dictionary attack (which is why you should ideally reject passwords that are plain words) - briefly, this means that the attacker calculates the hash of a large number of words and attempts to find a matching hash in your table. Fortunately the salt makes this task extremely time-consuming; each entry has its own salt so each needs to be attacked individually. - Peter Disclaimer: I improvised this code off the cuff, so caveats apply. [This message has been edited by Peter den Haan (edited November 01, 2001).]
Hi Pete, all, I'm resurrecting this post because I am implementing a logon module and I have used Pete's code here successfully up to the point where I have to retrieve the password & salt from the database.
That's the way I build the SQL string to save the byte arrays into CHAR fields. Then to retrieve it out of the resultSet
But somewhere along the line the hashed password changes, because the retrieved hash never compares with the original. I've been discussing the situation and somebody mentioned that the retrieved byte array will be the same length as the field it was saved in, but how long is the hash that is produced on hashing in the first place? Any help would be appreciated! Regards Adam
I have seen things you people would not believe, attack ships on fire off the shoulder of Orion, c-beams sparkling in the dark near the Tennhauser Gate. All these moments will be lost in time, like tears in the rain.
Useful tip: When you validate a password (hashed or otherwise) against a database, DON'T READ the password from the database. Instead do a key lookup. For a simple example: SELECT COUNT(userid) FROM users WHERE userid = ? and cryptpwd = ? If the request fails (or in this case, the count is 0), reject the login. I used "COUNT()" here as a general example, but in many cases you might be retrieving actual data fields (just DON'T include the password!). The reason for this is that if someone breaks into the system, passwords won't be lying around for the taking (even an encrypted password can be useful). It's not the ultimate in security - anyone breaking in has the potential to bypass security entirely, and if they wanted to pick the system apart, they might be able to find the database buffers and ravage them, but it's a little extra lockdown for minimal cost.
An IDE is no substitute for an Intelligent Developer.
Joined: Oct 09, 2001
Hmm, yes I see what you mean but I�m using a salt that I store as well, and since I need the salt to encrypt the password, I would have to make another call to the database. At the moment, I get the record for the user logon name, and that includes the password and the salt. I take the salt to encrypt the password the user typed in, to be able to compare it to the password from the database. What format are the database buffers in? Are you talking about a log of the sql executed statements, or do you mean cached result sets?