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

时间:2008-11-26 03:03:22

标签: java exception encryption cryptography

可以找到〜/ Cipher / nsdl / crypto中的所有文件here 用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).");
        }
    }
}
}

2 个答案:

答案 0 :(得分:2)

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

请注意catch构造函数中的BlockCrypt块。它捕获没有消息的异常,并将“null”打印到System.err

,而不是通过从构造函数中抛出异常来中止执行 - 而不是中止执行。

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

答案 1 :(得分:0)

或许看the source for javax.crypto.Cipher这有帮助吗?即使在源代码中找到错误消息,我也无法弄明白。祝你好运!