January 17, 2021
Hot Topics:

Unlocking the Secrets of Java Cryptography Extensions: The Basics

  • By David Thurmond
  • Send Email »
  • More Articles »

The subsequent differences occur when requesting a cipher for encrypting and decrypting data. The call to Cipher.getInstance() takes the optional provider-name parameter "BC", which requests that the implementation of the cipher be created from the provider's libraries.

The remainder of the code is not provider-specific, so one can code using the JCE without being locked in to a particular provider's libraries. Key generation, encryption, and decryption are all done in the same way, regardless of whether the Sun JCE provider or a third-party provider is used.

A More Realistic Example

The examples above do a good job of getting across basic concepts, but a few important points are left out. First, the examples use the same key object to encrypt and decrypt the data. In real life, it is likely that the party who wishes to decrypt the data will receive the key separately, perhaps contained in a file, rather than being hard-coded within the program. Second, the simple examples only encrypt and decrypt a small amount of data, a single text string, rather than a more realistic example, such as a large data file containing sensitive information. Listings 3.1 and 3.2 show examples that demonstrate how to perform these tasks.

package com.dlt.developer.crypto;

import javax.crypto.*;
import java.io.*;

 * @author David Thurmond
 * An example of encrypting a text file
 * using Data Encryption Standard encryption.
public class EncryptFileExample {
   public static void main(String[] args) throws Exception {
      // First, create the encryption key...
      System.out.println("Generating key");

      KeyGenerator keygen = KeyGenerator.getInstance("DES");
      SecretKey desKey = keygen.generateKey();

      System.out.println("Writing key to file...");
      byte[] keyBytes = desKey.getEncoded();

      System.out.println("Writing bytes = " + keyBytes.length);
      BufferedOutputStream out =
         new BufferedOutputStream(new FileOutputStream

      // Now, create the cipher object with appropriate parameters...
      System.out.println("Encrypting file using DES/ECB/PKCS5Padding");
      Cipher desCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
      desCipher.init(Cipher.ENCRYPT_MODE, desKey);

      System.out.println("Reading cleartext file and encrypting...");
      BufferedOutputStream outData =
         new BufferedOutputStream(new FileOutputStream
      BufferedInputStream in =
         new BufferedInputStream(new FileInputStream
      while (in.available() > 0) {
         byte[] cleartextBytes = new byte[in.available()];
         // Now, encrypt them and write them to the encrypted file...
         byte[] encryptedBytes = desCipher.update(cleartextBytes);

         outData.write(encryptedBytes, 0, encryptedBytes.length);
      }    // while
      // Take care of any pending padding operations

   }    // main

}    // EncryptFileExample

Listing 3.1: EncryptFileExample

The preceding example code first creates an encryption key and saves it to a file called encrypted_key.txt for later retrieval by a decryption program. The line:

byte[] keyBytes = desKey.getEncoded();

grabs the raw data for the key so that it can be saved to the file. The party who wants to decrypt the data file must know what kind of key was saved to the file, in this case a DES key in ECB format with PKCS-5 padding, to properly read it and create the decryption key.

Next, the file cleartext.txt, which is the unencrypted data file, is read in chunks of data. As each chunk is read, a block of data is encrypted and written out to the encrypted file encrypted_data.txt. To encrypt the data, the line:

byte[] encryptedBytes = desCipher.update(cleartextBytes);

takes the cleartext bytes just read from the file and converts them to ciphertext. This is slightly different than the invocation of doFinal() in the earlier examples. The Cipher.update() method assumes that there will be more blocks of data to be encrypted, and does not take care of any final padding that must be done for the cipher's algorithm to be properly applied. This is addressed by the line:


This finishes doing any remaining encryption and pads the resulting ciphertext appropriately, so that the total number of bytes of ciphertext is correct for the DES algorithm with PKCS-5 padding. Without this final call, the deciphering program could not decrypt the last bit of data in the file.

Page 4 of 6

This article was originally published on October 15, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date