views:

346

answers:

2

all files in ~/Cipher/nsdl/crypto can be found here java files compiled with gcj, see compile.sh

nmint@nqmk-mint ~/Cipher/nsdl/crypto $ echo test | ./cryptTest encrypt deadbeefdeadbeefdeadbeefdeadbeef deadbeef Blowfish CBC > test
null
Exception in thread "main" java.lang.IllegalStateException: cipher is not for encrypting or decrypting
   at javax.crypto.Cipher.update(libgcj.so.81)
   at javax.crypto.CipherOutputStream.write(libgcj.so.81)
   at nsdl.crypto.BlockCrypt.encrypt(cryptTest)
   at nsdl.crypto.cryptTest.main(cryptTest)

BlockCrypt.java:

package nsdl.crypto;

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

public class BlockCrypt {
Cipher ecipher;
Cipher dcipher;
byte[] keyBytes;
byte[] ivBytes;
SecretKey key;
AlgorithmParameterSpec iv;
byte[] buf = new byte[1024];

BlockCrypt(String keyStr, String ivStr, String algorithm, String mode) {
 try {
  ecipher = Cipher.getInstance(algorithm + "/" + mode + "/PKCS5Padding");
  dcipher = Cipher.getInstance(algorithm + "/" + mode + "/PKCS5Padding");

  keyBytes = hexStringToByteArray(keyStr);
  ivBytes = hexStringToByteArray(ivStr);

  key = new SecretKeySpec(keyBytes, algorithm);
  iv = new IvParameterSpec(ivBytes);

  ecipher.init(Cipher.ENCRYPT_MODE, key, iv);
  dcipher.init(Cipher.DECRYPT_MODE, key, iv);
 } catch (Exception e) {
  System.err.println(e.getMessage());
 }
}

public void encrypt(InputStream in, OutputStream out) {
 try {
  // out: where the plaintext goes to become encrypted
  out = new CipherOutputStream(out, ecipher);

  // in: where the plaintext comes from
  int numRead = 0;
  while ((numRead = in.read(buf)) >= 0) {
   out.write(buf, 0, numRead);
  }
  out.close();
 } catch (IOException e) {
  System.err.println(e.getMessage());
 }
}

public void decrypt(InputStream in, OutputStream out) {
 try {
  // in: where the plaintext come from, decrypted on-the-fly
  in = new CipherInputStream(in, dcipher);

  // out: where the plaintext goes
  int numRead = 0;
  while ((numRead = in.read(buf)) >= 0) {
   out.write(buf, 0, numRead);
  }
  out.flush();
  out.close();
 } catch (IOException e) {
  System.err.println(e.getMessage());
 }
}
public static byte[] hexStringToByteArray(String s) {
 int len = s.length();
 byte[] data = new byte[len / 2];
 for (int i = 0; i < len; i += 2) {
  data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
  + Character.digit(s.charAt(i+1), 16));
 }
 return data;
}
}

cryptTest.java:

package nsdl.crypto;

import nsdl.crypto.BlockCrypt;

public class cryptTest {

public static void main (String args[]) {
 if (args.length != 5) {
  System.err.println("Usage: cryptTest (encrypt|decrypt) key iv algorithm mode");
  System.err.println("Takes input from STDIN. Output goes to STDOUT.");
 } else {
  String operation = args[0];
  String key = args[1];
  String iv = args[2];
  String algorithm = args[3];
  String mode = args[4];
  BlockCrypt blockCrypt = new BlockCrypt(key, iv, algorithm, mode);
  if (operation.equalsIgnoreCase("encrypt")) {
   blockCrypt.encrypt(System.in, System.out);
  } else if (operation.equalsIgnoreCase("decrypt")) {
   blockCrypt.decrypt(System.in, System.out);
  } else {
   System.err.println("Invalid operation. Use (encrypt|decrypt).");
  }
 }
}
}
A: 

Perhaps looking at the source for javax.crypto.Cipher helps this make sense? I couldn't really figure it out, even finding the error message in the source. Good luck!

Ray
+2  A: 
erickson
Thanks for taking the time to answer.If I make sure the IV is 64bits, the program works perfectly!You'll get in the credits when I finish my science fair project.(I don't really know what else I can do to thank you - I'm only an eighth grader.)
InsDel