Link to home
Start Free TrialLog in
Avatar of bobwood2000
bobwood2000

asked on

Cipher parameters for non-EBC mode encryption & decryption

It seems that when I encrypt & decrypt data using a Cipher in EBC mode, I do not need to specify any parameters beyond the algorithm string (e.g. "AES/EBC/PKCS5Padding"). However, I want to use CBC or OFB mode. These modes seem to require additionally parameters. What information do these additional parameters contain? For example, do they contain an initialization vector? If so, I would certainly somehow need to share these additional parameters with the class that will be decrypting the data. The trouble is that the process that does decrypting is located on a different computer than the process doing the encrypting. Since all data passed between these classes will be encrypted, if the decrypting process is sent these parameters, it will not be able to decrypt the parameters until it has the parameters. Paradoxical I suppose, but there must be some standard way to solve this situation. Suggestions?

Thanks.
Avatar of TZRick
TZRick

EBC is short for Electronic Codebook Mode. Simply put, it means that each character (or byte or whatever unit is used) is encrypted to one and the same resulting ciphertext. For example, if I encrypt "a" using ECB, then it will always result in, say, a "t". This way, hackers can decipher the ciphertext by simply looking for patterns in the ciphertext.

Cipher Block Chaining and Output Feedback Mode are ways to 'chain' the blocks of plaintext so that the previous ciphertext blocks affect the next block. CBC is risky as an error in the ciphertext may make decryption impossible, even if the error is in one block. OFB is safer, as over a certain number of blocks, any error attenuates, so that most of the plaintext can be retrieved if only a few blocks of ciphertext are distorted.

To answer your question, yes, an initialization vector is required in addition to the key.
I shall post some code I did when I just began learning Java (and completing a Cryptography project at the same time):

This is one class called Cloak. It is the main class used for encryption and decryption. Hope this helps! :-)

Taarik.

import java.io.*;
import java.security.*;

import javax.crypto.*;
import javax.crypto.spec.*;

public class Cloak {
      
      public static final int kBufferSize = 8192;
      
      public final boolean Cloak () {
            
            return true;                                    //Bad command
            
      }
      
      public final boolean Cloak (boolean encrypt, int modeselect,
            String fileinput, String fileoutput, byte [] InitVecByte, byte [] PriKey,
            boolean GeneratePriKey, int PriKeyfileoption, String PriKeyfile)
            throws Exception {
                  
            Key key = null;                                    //Stores key
            String mode;                                    //Stores encryption mode
            String keystring = null;                  //Used to display key in string form
            IvParameterSpec InitVec;                  //Initialization Vector
            InitVec = null;
                  
            //Create new IV if InitVecByte is not null.
            if (InitVecByte != null)
            
                  InitVec = GetIV (InitVecByte);
            
            //Gets the mode as a string.
            mode = Mode (modeselect);
            
            if (GeneratePriKey == true) {
                  
                  key = GetKey ();                        //Generate new key
                  
            }
            
            else {
                  
                  if (PriKeyfileoption == 1)
                        
                        key = GetKey (PriKeyfile);      //Retrieve key from file
                        
                  else {
                        
                        key = GetKey (PriKey);            //Use user-defined key
                                                
                  }
                  
            }

            //Print Key in string form to console                        
            keystring = new String (key.getEncoded());
            System.out.println ("Key in use: " + keystring);
                  
            
            
            if (PriKeyfileoption == 2) {
                  
                  //Save key to file
                  ObjectOutputStream out = new ObjectOutputStream
                        (new FileOutputStream (PriKeyfile));
                  out.writeObject (key);
                  out.close ();
                  
            }
                        
            //Get a cipher object.
            Cipher cipher = Cipher.getInstance ("DES/" + mode +"/PKCS5Padding");
            
            //Encrypt or decrypt.
            if (encrypt == true)
            
                  if (InitVec != null)
                  
                        //Initialize cipher object using provided IV
                        cipher.init (Cipher.ENCRYPT_MODE, key, InitVec);
                        
                  else
                  
                        //Initialize cipher object using newly-generated IV
                        cipher.init (Cipher.ENCRYPT_MODE, key);
                  
            else
            
                  if (InitVec != null)
                  
                        //Initialize cipher object using provided IV
                        cipher.init (Cipher.DECRYPT_MODE, key, InitVec);
                        
                  else
                        
                        //Initialize cipher object using newly-generated IV
                        cipher.init (Cipher.DECRYPT_MODE, key);
                  
            //Save current IV to protected variable
            Cryptography.kWorkingIV = cipher.getIV ();
            
            //Read contents from source file
            FileInputStream in = new FileInputStream (fileinput);
            
            //Write contents to destination file.
            FileOutputStream fileOut = new FileOutputStream (fileoutput);
            CipherOutputStream out = new CipherOutputStream (fileOut, cipher);
            byte [] buffer = new byte [kBufferSize];
            int length;
            
            while ((length = in.read(buffer)) != -1)
            
                  out.write (buffer, 0, length);
                  
            if (encrypt == true) {
                  
                  System.out.println ("Encryption Success.");
                  
                  
            }
            
            else {
                  
                  System.out.println ("Decryption Success.");
                                    
            }
                  
            in.close ();
            out.close ();
            
            return false;
            
      }
      
      private String Mode (int modeselect) {
            
            switch (modeselect) {
                  
                  case 0:
                        
                        return "ECB";
                                          
                  case 1:
                        
                        return "CBC";
                                                
                  case 2:
                  
                        return "CFB";
                                                
                  default:
                        
                        return "ECB";
                                                
            }
            
      }
      
      //Generate random key
      private Key GetKey () {
            
            try {
                  
                  KeyGenerator generator = KeyGenerator.getInstance("DES");
                  generator.init (new SecureRandom ());
                  return generator.generateKey();                  //Return a SecretKey
                  
            }
            
            catch (Exception e) {
                  
                  System.out.println (e);
                  
            }
            
            return null;
            
      }
      
      //Retrieve key from file
      private Key GetKey (String Keyfile) {
            
            Key key = null;
            
            try {
                  
                  ObjectInputStream in = new ObjectInputStream (new FileInputStream (Keyfile));
                  key = (Key)in.readObject ();
                  in.close ();
                  
            }
            
            catch (Exception e) {
                        
                  System.out.println (e);
                  return key;
                        
            }
            
            return key;                                                      //Return a Key
      }
      
      //Create new key from user-supplied string
      private Key GetKey (byte [] KeyBytes) {
            
            byte [] temp = new byte [8];
            int length = KeyBytes.length;
                        
            for (int counter = 0; counter < 8; counter++) {
            
                  if (counter > length - 1) {
                        
                        temp [counter] = (byte) (8 - counter);
                  
                        
                  }
                  
                  else {
                        
                        temp [counter] = KeyBytes [counter];
                        
                  }
                  
            }
                        
            SecretKeySpec key = new SecretKeySpec (temp, "DES");
            
            return key;                                                      //Return a Key (SecretKeySpec)
      
      }
      
      private IvParameterSpec GetIV (byte [] InitVecByte) {
                        
            byte [] temp = new byte [8];
            int length = InitVecByte.length;
                                    
            if (InitVecByte != null) {
            
                  for (int counter = 0; counter < 8; counter++) {
            
                        if (counter > length - 1) {
                        
                              temp [counter] = (byte) (8 - counter);
                  
                        
                        }
                  
                        else {
                        
                              temp [counter] = InitVecByte [counter];
                        
                        }
                  
                  }
                  
                  return new IvParameterSpec (temp, 0, 8);
                                                      
            }
            
            return null;
                  
      }
      
}
ASKER CERTIFIED SOLUTION
Avatar of TZRick
TZRick

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of bobwood2000

ASKER

Your right...using anything but EBC doesn't make much sense if your not going to exchange the session parameters using public key cryptography.