Symmetric-Key Cryptography is an encryption system in which the same key is used for the encoding and decoding of the data. The safe distribution of the key is one of the drawbacks of this method, but what it lacks in security it gains in time complexity.

One should always assume that the encryption algorithms are publicly known and not rely on “Security through obscurity”. The most popular Symmetric Algorithms are DES, Triple-DES, AES, Blowfish, RC2, RC4(ARCFOUR), RC5, RC6.

1. Use Case of Symmetric Key Cryptography

Below you can see the code of an application that uses Symmetric-Key Cryptography to encrypt or decrypt a pre-set directory. The constructor is initialized with the password, the length of the key and the algorithm that will be used for the cipher. To learn more about the key lengths for each algorithm refer to Import Limits on Cryptographic Algorithms.

Note
If you want to read more about Encryption Algorithms, refer to Performance Analysis of Data Encryption Algorithms: 2.5 Compared Algorithms

In this example we use AES as it is considered the silver lining between speed and security.

SymmetricKeyExample.java

package com.mkyong.symmetric;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.JOptionPane;

public class SymmetricKeyExample {
	private SecretKeySpec secretKey;
	private Cipher cipher;

	public SymmetricKeyExample(String secret, int length, String algorithm)
			throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException {
		byte[] key = new byte[length];
		key = fixSecret(secret, length);
		this.secretKey = new SecretKeySpec(key, algorithm);
		this.cipher = Cipher.getInstance(algorithm);
	}

	private byte[] fixSecret(String s, int length) throws UnsupportedEncodingException {
		if (s.length() < length) {
			int missingLength = length - s.length();
			for (int i = 0; i < missingLength; i++) {
				s += " ";
			}
		}
		return s.substring(0, length).getBytes("UTF-8");
	}

	public void encryptFile(File f)
			throws InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
		System.out.println("Encrypting file: " + f.getName());
		this.cipher.init(Cipher.ENCRYPT_MODE, this.secretKey);
		this.writeToFile(f);
	}

	public void decryptFile(File f)
			throws InvalidKeyException, IOException, IllegalBlockSizeException, BadPaddingException {
		System.out.println("Decrypting file: " + f.getName());
		this.cipher.init(Cipher.DECRYPT_MODE, this.secretKey);
		this.writeToFile(f);
	}

	public void writeToFile(File f) throws IOException, IllegalBlockSizeException, BadPaddingException {
		FileInputStream in = new FileInputStream(f);
		byte[] input = new byte[(int) f.length()];
		in.read(input);

		FileOutputStream out = new FileOutputStream(f);
		byte[] output = this.cipher.doFinal(input);
		out.write(output);

		out.flush();
		out.close();
		in.close();
	}

	public static void main(String[] args) {
		File dir = new File("src/cryptodir");
		File[] filelist = dir.listFiles();

		SymmetricKeyExample ske;
		try {
			ske = new SymmetricKeyExample("!@#$MySecr3tPassw0rd", 16, "AES");

			int choice = -2;
			while (choice != -1) {
				String[] options = { "Encrypt All", "Decrypt All", "Exit" };
				choice = JOptionPane.showOptionDialog(null, "Select an option", "Options", 0,
						JOptionPane.QUESTION_MESSAGE, null, options, options[0]);

				switch (choice) {
				case 0:
					Arrays.asList(filelist).forEach(file -> {
						try {
							ske.encryptFile(file);
						} catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException
								| IOException e) {
							System.err.println("Couldn't encrypt " + file.getName() + ": " + e.getMessage());
						}
					});
					System.out.println("Files encrypted successfully");
					break;
				case 1:
					Arrays.asList(filelist).forEach(file -> {
						try {
							ske.decryptFile(file);
						} catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException
								| IOException e) {
							System.err.println("Couldn't decrypt " + file.getName() + ": " + e.getMessage());
						}
					});
					System.out.println("Files decrypted successfully");
					break;
				default:
					choice = -1;
					break;
				}
			}
		} catch (UnsupportedEncodingException ex) {
			System.err.println("Couldn't create key: " + ex.getMessage());
		} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
			System.err.println(e.getMessage());
		}
	}
}

Output

java-symmetrickey-output-1

When the button “Encrypt All” is clicked.


Encrypting file: Hello world.docx
Encrypting file: Hello world.pdf
Encrypting file: Smiley.png
Encrypting file: Text.txt
Files encrypted successfully

When the button “Decrypt All” is clicked.


Decrypting file: Hello world.docx
Decrypting file: Hello world.pdf
Decrypting file: Smiley.png
Decrypting file: Text.txt
Files decrypted successfully

Original text file.

src/Text.txt

This is a text file.

Text file is encrypted.

src/Text.txt

‡(?ê?z@ou7ÿ—pø"é³.Õ0Ò;jVi¶‚

Be advised: Before you run this code creates a separate directory with files just for the purposes of this example. Download the source code below if you do not know exactly what you are doing.

2. Project Directory

java-symmetrickey-example

Download Source Code

References

  1. Security through obscurity
  2. Performance Analysis of Data Encryption Algorithms: 2.5 Compared Algorithms
  3. Import Limits on Cryptographic Algorithms
  4. Cipher Algorithms