Tutorial: Java DES Encryption And Decryption

The Data Encryption Standard (DES) is a block cipher (a form of shared secret encryption) that was selected by the National Bureau of Standards as an official Federal Information Processing Standard (FIPS) for the United States in 1976 and which has subsequently enjoyed widespread use internationally. It is based on a symmetric-key algorithm that uses a 56-bit key. The algorithm was initially controversial with classified design elements, a relatively short key length, and suspicions about a National Security Agency (NSA) backdoor. DES consequently came under intense academic scrutiny which motivated the modern understanding of block ciphers and their cryptanalysis.

DES is now considered to be insecure for many applications. This is chiefly due to the 56-bit key size being too small; in January, 1999, distributed.net and the Electronic Frontier Foundation collaborated to publicly break a DES key in 22 hours and 15 minutes. There are also some analytical results which demonstrate theoretical weaknesses in the cipher, although they are unfeasible to mount in practice. The algorithm is believed to be practically secure in the form of Triple DES, although there are theoretical attacks. In recent years, the cipher has been superseded by the Advanced Encryption Standard (AES).

In some documentation, a distinction is made between DES as a standard and DES the algorithm which is referred to as the DEA (the Data Encryption Algorithm). (Source: Wikipedia. See LicenseTerms)

In the following tutorial, I have tried to demonstrate in a very simple way:

  • How to do a DES Encryption of a plain text
  • How to decrypt a text that has once been encrypted using DES Encryption

Note that there is a secretKey involved (myEncryptionKey).

/**
 * Author - Kushal Paudyal
 * www.sanjaal.com/java
 * Last Modified On 06-19-2009
 */
package com.kushal.utils;

import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DESEncryption {

	private static final String UNICODE_FORMAT = "UTF8";
	public static final String DES_ENCRYPTION_SCHEME = "DES";
	private KeySpec myKeySpec;
	private SecretKeyFactory mySecretKeyFactory;
	private Cipher cipher;
	byte[] keyAsBytes;
	private String myEncryptionKey;
	private String myEncryptionScheme;
	SecretKey key;

	public DESEncryption() throws Exception
	{
		myEncryptionKey = "ThisIsSecretEncryptionKey";
		myEncryptionScheme = DES_ENCRYPTION_SCHEME;
		keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
		myKeySpec = new DESKeySpec(keyAsBytes);
		mySecretKeyFactory = SecretKeyFactory.getInstance(myEncryptionScheme);
		cipher = Cipher.getInstance(myEncryptionScheme);
		key = mySecretKeyFactory.generateSecret(myKeySpec);
	}

	/**
	 * Method To Encrypt The String
	 */
	public String encrypt(String unencryptedString) {
		String encryptedString = null;
		try {
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
			byte[] encryptedText = cipher.doFinal(plainText);
			BASE64Encoder base64encoder = new BASE64Encoder();
			encryptedString = base64encoder.encode(encryptedText);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return encryptedString;
	}
	/**
	 * Method To Decrypt An Ecrypted String
	 */
	public String decrypt(String encryptedString) {
		String decryptedText=null;
		try {
			cipher.init(Cipher.DECRYPT_MODE, key);
			BASE64Decoder base64decoder = new BASE64Decoder();
			byte[] encryptedText = base64decoder.decodeBuffer(encryptedString);
			byte[] plainText = cipher.doFinal(encryptedText);
			decryptedText= bytes2String(plainText);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return decryptedText;
	}
	/**
	 * Returns String From An Array Of Bytes
	 */
	private static String bytes2String(byte[] bytes) {
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			stringBuffer.append((char) bytes[i]);
		}
		return stringBuffer.toString();
	}

	/**
	 * Testing the DES Encryption And Decryption Technique
	 */
	public static void main(String args []) throws Exception
	{
		DESEncryption myEncryptor= new DESEncryption();

		String stringToEncrypt="Sanjaal.com";
		String encrypted=myEncryptor.encrypt(stringToEncrypt);
		String decrypted=myEncryptor.decrypt(encrypted);

		System.out.println("String To Encrypt: "+stringToEncrypt);
		System.out.println("Encrypted Value :" + encrypted);
		System.out.println("Decrypted Value :"+decrypted);

	}	

}

=======================
Here is the sample output:

String To Encrypt:Sanjaal.com
Encrypted Value: x57YpwPaa4Wa4kIAURuT1A==
Decrypted Value :Sanjaal.com

[My Video Promotion]
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.