One Way Password Encryption Using Java

Wonder how your passwords are generally stored by the web applications? One thing for sure, they are not stored as plain text, if the developers out there care about your password security. In this little Java Tutorial, I would like to demonstrate how to generate an encrypted password that can be stored in the database and is safe. I will show how the change in encryption algorithm and encoding affects the generation of the encrypted password. There are varieties of encrypting algorithms, I am using SHA and MD5.

/**
 * @Author Kushal Paudyal
 * http://www.sanjaal.com/java
 * Last Modified On 2009-04-28
 */
package com.kushal.utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Encoder;

public final class MyPasswordEncrypt {
	public static synchronized String encrypt(String plaintext,
			String algorithm, String encoding) throws Exception {
		MessageDigest msgDigest = null;
		String hashValue = null;
		try {
			msgDigest = MessageDigest.getInstance(algorithm);
			msgDigest.update(plaintext.getBytes(encoding));
			byte rawByte[] = msgDigest.digest();
			hashValue = (new BASE64Encoder()).encode(rawByte);

		} catch (NoSuchAlgorithmException e) {
			System.out.println("No Such Algorithm Exists");
		} catch (UnsupportedEncodingException e) {
			System.out.println("The Encoding Is Not Supported");
		}
		return hashValue;
	}

	public static void main(String args[]) throws Exception {
		String plainPassword = "SecretPassword";

		System.out.println("PlainTexttAlgotEncodingtEncrypted Password");
		System.out.println(plainPassword + "tSHAtUTF-8t"
				+ encrypt("MySecretPassword", "SHA", "UTF-8"));
		System.out.println(plainPassword + "tSHA-1tUTF-16t"
				+ encrypt("MySecretPassword", "SHA-1", "UTF-16"));
		System.out.println(plainPassword + "tMD5tUTF-8t"
				+ encrypt("MySecretPassword", "MD5", "UTF-8"));
		System.out.println(plainPassword + "tMD5tUTF-16t"
				+ encrypt("MySecretPassword", "MD5", "UTF-16"));

	}
}

—————————————————-
Here is the output of this program. Note the different
Encrypted Passwords for the same Plain Text Password
—————————————————

PlainText	        Algo	   Encoding	Encrypted Password
SecretPassword	SHA	   UTF-8	lScpxhyrfgHktfW6e5WDDSB190s=
SecretPassword	SHA-1  UTF-16	NfsACTQRTvkEV5kzrDY55vQR1ec=
SecretPassword	MD5	   UTF-8	cxWgEuytEFmjY0+L4TR4Rg==
SecretPassword	MD5	   UTF-16	JulkQ6YpxzLMlpIgU28xmg==

————————————————–

If you are interested in understanding what is SHA /MD5 and UTF Encoding, read below:

SHA
The SHA hash functions are a set of cryptographic hash functions designed by the National Security Agency (NSA) and published by the NIST as a U.S. Federal Information Processing Standard. SHA stands for Secure Hash Algorithm. The three SHA algorithms are structured differently and are distinguished as SHA-0, SHA-1, and SHA-2. The SHA-2 family uses an identical algorithm with a variable digest size which is distinguished as SHA-224, SHA-256, SHA-384, and SHA-512.

SHA-1 is the best established of the existing SHA hash functions, and is employed in several widely used security applications and protocols. In 2005, security flaws were identified in SHA-1, namely that a possible mathematical weakness might exist, indicating that a stronger hash function would be desirable. Although no attacks have yet been reported on the SHA-2 variants, they are algorithmically similar to SHA-1 and so efforts are underway to develop improved alternatives. A new hash standard, SHA-3, is currently under development the function will be selected via an open competition running between 2008 and 2012. [From Wikipedia. See License Terms]

MD5
In cryptography, MD5 (Message-Digest algorithm 5) is a widely used cryptographic hash function with a 128-bit hash value. As an Internet standard (RFC 1321), MD5 has been employed in a wide variety of security applications, and is also commonly used to check the integrity of files. However, it has been shown that MD5 is not collision resistant; as such, MD5 is not suitable for applications like SSL certificates or digital signatures that rely on this property. An MD5 hash is typically expressed as a 32 digit hexadecimal number.

MD5 was designed by Ron Rivest in 1991 to replace an earlier hash function, MD4. In 1996, a flaw was found with the design of MD5. While it was not a clearly fatal weakness, cryptographers began recommending the use of other algorithms, such as SHA-1 (which has since been found vulnerable). In 2004, more serious flaws were discovered, making further use of the algorithm for security purposes questionable. In 2007 a group of researchers including Arjen Lenstra described how to create a pair of files that share the same MD5 checksum. In an attack on MD5 published in December 2008, a group of researchers used this technique to fake SSL certificate validity. [From Wikipedia. See License Terms]

UTF
UTF Stands for Unicode Transformation Format. It is one of the method of character encoding for unicode.

Tagged , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

9 Responses to Tutorial – Encryption And Decryption Using DESede (Triple DES) In Java

  1. Modha says:

    Hello Kushal

    I enjoyed reading your articles ( and jokes ) at sanjaal.

    I have a question on encryption and decryption
    http://sanjaal.com/java/2009/06/19/tutorial-encryption-and-decryption-using-desede-triple-des-in-java/

    will this work only on UTF-8?

    I want to write a utility which encrypts a column in a database table.

    Can I use this program to read string from a database table – encrypt it and – write it back.

    Will it work if database in not in UTF-8, (I am trying to ask if it can encode some other charecter set like chinese or japanese)?
    I am trying to learn what these charecter encodings mean, excuse me if my question are basic.

    Hope to get a reply.

    Thanks
    Modha/-

    • kushalzone says:

      Thank you Modha for enjoying my blogs at Sanjaal.

      Yes, the program is capable of handling the other character sets like ASCII, UTF-16 etc. UTF-8 is the unicode format, so most probably the japanese or chinese characters will be in this Character Set.

      If you know exactly what character set your database is using, you can pass that onto the getBytes () method as parameter, and do the encryption/decryption. The character sets will be defined while creating the database or database tables.

      For example, if your database character set is UTF-16, you can modify the above program where it says

      byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);

      to

      byte[] plainText = unencryptedString.getBytes(“UTF-16”);

      Or, if the character set defined is ASCII, you simply define the line as:

      byte[] plainText = unencryptedString.getBytes(“ASCII”);

      Also make sure you modify the following line accordingly:
      keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);

      I hope it helps.

  2. Raanan says:

    Hi,

    Thanks for the post !!

    I have 2 questions:

    i. in your your example you wrote “…In the following tutorial, we have used Keying Option 3, where all the keys are identical.” – what make the code use option 3?

    ii. if I have a byte array that is used to build a DESedeKeySpec instance, can I tell which length is the encryption key (168 or 112)?

    Thanks,
    Raanan.

  3. Minal says:

    Hi,

    This article is very helpful. I am trying to encrypt and decrypt using DES but getting following error
    javax.crypto.BadPaddingException: Given final block not properly padded
    I tried all possible ways but problem is not solved yet. I appreciate if you could hlep me in this regards

    Thanks
    Minal

  4. Send the code that you are trying to run, I will have a look at it.

  5. Minal says:

    code to get cipher is
    —————————–
    key = InternalSecretKey.getInstance();
    //keyspec = InternalSecretKey.getInstance();
    System.out.println(“Key is:”+key);

    byte[] iv = new byte[]{
    (byte)0x8E, 0x12, 0x39, (byte)0x9C,
    0x07, 0x72, 0x6F, 0x5A
    };
    //byte[] ivBytes = null;
    //IvParameterSpec iv = new IvParameterSpec(ivBytes);
    //IvParameterSpec iv = null;

    //ecipher = Cipher.getInstance(“DES”);
    //dcipher = Cipher.getInstance(“DES”);

    ecipher = Cipher.getInstance(“DES/CBC/NoPadding”);
    dcipher = Cipher.getInstance(“DES/CBC/NoPadding”);

    AlgorithmParameterSpec algparam = new IvParameterSpec(iv);
    //IvParameterSpec iv = null;

    System.out.println(” iv ====================” + ecipher.getIV());
    //iv = new IvParameterSpec(ivBytes);

    //IvParameterSpec iv2 = new IvParameterSpec(dcipher.getIV());

    AlgorithmParameters algparamdecrypt = ecipher.getParameters();
    ecipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, algparam);
    dcipher.init(javax.crypto.Cipher.DECRYPT_MODE, key, algparam);

    ——————————————-
    I tryed padding input stream before encryptin

    byte[] padding = null;
    byte padded[] = null;
    if (null != fileData) {

    System.out.println(“length of byte arrary before ency but before padding ” + fileData.length);
    if((fileData.length % 8) > 0){
    int offset = ((fileData.length % 8));
    System.out.println(” offset is ” + offset);
    padding = new byte[((8-offset) + fileData.length)];
    System.out.println(“lenght of fileData is ” + fileData.length);
    System.out.println(“lenght of padding is ” + padding.length);
    System.arraycopy(fileData, 0, padding, 0, fileData.length);
    for(int i = fileData.length; i < (fileData.length + (8-offset)); i++){
    padding[i] = (byte)0xbb;
    }
    System.out.println(" padding " + padding.toString());
    System.out.println(" fileData " + fileData.toString());

    System.out.println("length of byte arrary before ency but after padding ==" + padding.length);

    }
    }
    AesEncryptionDecryptionUtil endeUtil = new AesEncryptionDecryptionUtil();
    byte[] fileDataEnc = null;
    if(padding != null){
    fileDataEnc = ecipher.doFinal(padding);
    }else{
    fileDataEnc = ecipher.doFinal(fileData);
    System.out.println("Bytes encrypted:"+fileDataEnc.toString());

    —————————————————–
    With this padding logic code might work for .txt, .doc and .xls. However if I want to ebcrypt pdf, image files or zip files what is to be done?

    Thanking in advance

  6. Minal says:

    I would also like to know that if I am using cipher to encrypt the data, and encrypted data is stored in file/database. Next time when I decrypt the data do I need same instance of cipher which was used to encrypt the data (ofcourse with mode as decryption) or differnect instance created by passing same parameters can be used?

  7. webuser says:

    Getting wroung key size
    Exception in thread “main” java.security.InvalidKeyException: Wrong key size

  8. Fabian says:

    HI,

    I have a question,

    Which key do you use in your sample? I need decrypt it:

    Text: D64A1C4C83C16917
    Key: CF21BCFB0C4CB6E3

    I tried to use some web for this but I canĀ“t do it.

    Can you help me, thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.