你能弄清楚为什么这个程序会触发IllegalStateException吗?

〜/ Cipher / nsdl / crypto中的所有文件都可以在这里找到用gcj编译的java文件,参见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)."); } } } } 

Cipher, ecipher ,未初始化,当您尝试使用它时,它会抛出IllegalStateException ,就像它在ENCRYPT_MODE中初始化一样。

请注意BlockCrypt构造函数中的catch块。 它捕获没有消息的exception,并向System.err打印“null”。 而不是中止执行 – 也许是通过从构造函数中抛出exception – 你继续航行。

e.printStackTrace()或至少System.err.println(e)替换System.err.println(e.getMessage()) System.err.println(e)可以为您提供更多详细信息。 我的猜测是ecipher.init()抛出exception,因为你提供的是32位IV而不是64位。

或许查看javax.crypto.Cipher的源代码有助于理解这一点吗? 即使在源代码中找到错误消息,我也无法弄明白。 祝你好运!