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.
Thanks.
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;
}
}
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("
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Check out http://www.rsasecurity.com/rsalabs/node.asp?id=2165 for an explanation.
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.
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.