Java Program 1 for Triple-DES Encryption with Cipher Block Chaining

by J. Orlin Grabbe


This program, test3des1_CBC.java is a variation on the test3des1.java program.

The program here uses CBC mode (Cipher Block Chaining mode) to encrypt the data. First a random 8-byte (64-bit) Initialization Vector is appended to the beginning of the data. This block is encrypted first; then the encrypted block is XOR'd with the next plain text block (the first 8 bytes of the target file to be encrypted) before it is encrypted. The result of that encryption is then X0R'd with the next plain text block (the second 8 bytes of the target file) before that block is encrypted. And so on.

Note: If you do not append the Initialization Vector to the beginning of the string to be encrypted, the encrypted text will not decrypt properly; rather, the first 8 bytes will be garbled. But with the Initialization Vector appended to the beginning of the string to be encrypted, the subsequent decryption will yield an extraneous garbage vector as the first 8 bytes of the decrypted text. At that point the first 8 bytes can be disgarded, leaving the original plaintext file.

The test3des1_CBC.java program:

  • takes the 3DES key input from the program itself (not from a file),

  • prints out an 8-byte Initialization Vector from a string in the program,

  • uses as the string to be encrypted one with this Intialization Vector as the first 8 bytes;

  • encrypts the string in cipher block chaining (CBC) mode (to produce the ciphertext),

  • writes the key and the ciphertext to a file DES-EDE3.out,

  • decrypts the ciphertext (still in computer memory), and writes the resulting plaintext string to the file.
  • In this example, we see see the following five numbers:

  • 3DES key: 3812A419C63BE771 AD9F61FEFA20CE63 3812A419C63BE771

  • Initilization Vector: CCF3454D1E9CCDE0

  • Plaintext with Initialization Vector : CCF3454D1E9CCDE0 0101010101010101 0102030405060708 090A0B0C0D0E0F10 1112131415161718

  • Ciphertext: 5D505DD99BC8AC65 B25D48D2A6755630 D987EEEDD7E10F63 0EAE5063EC17B0C6 8E37124A8E4C6B13

  • Decrypted Ciphertext (disgard first 8 bytes) : 42C4570790D0A6F3 0101010101010101 0102030405060708 090A0B0C0D0E0F10 1112131415161718


  • Java Source Code

    test3des1_CBC.java


    mport java.io.*;
    import java.security.*;
    import java.math.*;
    import cryptix.util.core.BI;
    import cryptix.util.core.ArrayUtil;
    import cryptix.util.core.Hex;
    import cryptix.provider.key.*;
    
    class test3des1_CBC {
    
    public static void main (String[] args) {
    
            try {
            FileOutputStream outFile1 = new FileOutputStream("DES-EDE3.out");
            // Note: PrintStream is deprecated, but still works fine in jdk1.1.7b
            PrintStream output1 = new PrintStream(outFile1); 
    
          // convert a string to a 3DES key and print out the result
        RawSecretKey key2 = new RawSecretKey(" DES-EDE3",Hex.fromString("3812A419C63BE771AD9F61FEFA20CE633812A419C63BE771"));
        RawKey rkey = (RawKey) key2;
            byte[] yval = rkey.getEncoded();
            BigInteger Bkey = new BigInteger(yval);
            String w = cryptix.util.core.BI.dumpString(Bkey);
            output1.println("The Encryption Key = " + w);
            
            // convert a string to an initialization vector and print out the result
    	byte[] iv = new byte[8];
    	iv = Hex.fromString("CCF3454D1E9CCDE0");
            Bkey = new BigInteger(iv);
            w = cryptix.util.core.BI.dumpString(Bkey);
            output1.println("The Initialization Vector = " + w);
    
            // use the 3DES key and initialization vector to encrypt a string in cipher block chaining (CBC) mode
            Cipher des=Cipher.getInstance("DES-EDE3/CBC/NONE","Cryptix");
            des.initEncrypt(key2);  
            byte[] ciphertext = des.crypt(Hex.fromString("CCF3454D1E9CCDE001010101010101010102030405060708090A0B0C0D0E0F101112131415161718"));
    
            // print out length and representation of ciphertext 
            output1.print("\n");
            output1.println("ciphertext.length = " + ciphertext.length);
    
            BigInteger Bciph = new BigInteger(ciphertext);
            w = cryptix.util.core.BI.dumpString(Bciph);
            output1.println("Ciphertext resulting from 3DES encryption = " + w);
            
            // decrypt ciphertext 
            des.initDecrypt(key2);
            ciphertext = des.crypt(ciphertext);
            output1.print("\n");
            output1.println("plaintext.length = " + (ciphertext.length-8));
    
            // print out representation of decrypted ciphertext (start with byte 9)
    	  byte[] bt = new byte[ciphertext.length-8];
    	  int i;
    	  for(i=8;i<ciphertext.length;i++) bt[i-8] = ciphertext[i];
            Bciph = new BigInteger(bt);
            w = cryptix.util.core.BI.dumpString(Bciph);
            output1.println("Plaintext for 3DES encryption = " + w);
            output1.println(" ");
    		
              // print out representation of decrypted ciphertext (start with byte 0)
            Bciph = new BigInteger(ciphertext);
            w = cryptix.util.core.BI.dumpString(Bciph);
            output1.println("Plaintext with Garbage Vector = " + w);
    
            output1.println(" ");
            output1.close();                
    
          } catch (Exception e) {
                System.err.println("Caught exception " + e.toString());
          }
    
            }}
    		
    

    Sample Program Output

    DES-EDE3.out


    The Encryption Key = Multi-Precision Integer 190 bits long...
          sign: Positive
     magnitude: 3812A419C63BE771 AD9F61FEFA20CE63 3812A419C63BE771 
    
    The Initialization Vector = Multi-Precision Integer 62 bits long...
          sign: Negative
     magnitude: CCF3454D1E9CCDE0 
    
    ciphertext.length = 40
    Ciphertext resulting from 3DES encryption = Multi-Precision Integer 319 bits long...
          sign: Positive
     magnitude: Hexadecimal dump of 40 bytes...
       0: 5D505DD99BC8AC65 B25D48D2A6755630 D987EEEDD7E10F63 0EAE5063EC17B0C6 
      32: 8E37124A8E4C6B13 
    
    plaintext.length = 32
    Plaintext for 3DES encryption = Multi-Precision Integer 249 bits long...
          sign: Positive
     magnitude: 0101010101010101 0102030405060708 090A0B0C0D0E0F10 1112131415161718 
     
    Plaintext with Garbage Vector = Multi-Precision Integer 319 bits long...
          sign: Positive
     magnitude: Hexadecimal dump of 40 bytes...
       0: 42C4570790D0A6F3 0101010101010101 0102030405060708 090A0B0C0D0E0F10 
      32: 1112131415161718 
    


    J. Orlin Grabbe is the author of International Financial Markets, and is an internationally recognized derivatives expert who has recently branched out into cryptology, banking security, and digital cash. His home page is located at http://www.aci.net/kalliste/homepage.html. He currently resides in Costa Rica.

    Click here to return to Encryption Menu