2008-11-26 27 views
2

所有文件在〜/密码/ NSDL /加密可以发现GCJ编译here java文件,见compile.sh你能弄清楚为什么这个程序触发IllegalStateException吗?

[email protected] ~/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)."); 
     } 
    } 
} 
} 
+0

它可能有助于知道抛出异常。 – Darron 2008-11-26 03:12:59

+0

它说,在那里的抛出:在nsdl.crypto.BlockCrypt.encrypt(cryptTest) – Ray 2008-11-26 05:08:12

回答

2

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

注意的BlockCrypt构造你的catch块。它正在捕获一个没有消息的例外,并将“空”打印到System.err。而不是从—你保持帆船构造抛出一个异常中止执行—可能。

更换System.err.println(e.getMessage())e.printStackTrace()或至少System.err.println(e)应该给你更多的细节。我的猜测是ecipher.init()抛出一个异常,因为你提供了一个32位的IV,而不是64位。

相关问题