2008-11-26 7 views
2

tous les fichiers dans ~/Cipher/NSDL/Crypto se trouve here fichiers Java compilés avec gcj, voir compile.shPouvez-vous comprendre pourquoi ce programme déclenche une exception 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

Il peut être utile de savoir où l'exception est levée. – Darron

+0

Il dit où il est jeté: à nsdl.crypto.BlockCrypt.encrypt (cryptTest) – Ray

Répondre

2

Le Chiffre, ecipher, n'est pas initialisé et il lance un IllegalStateException lorsque vous essayez de l'utiliser comme s'il avait été initialisé en ENCRYPT_MODE. Notez votre bloc catch dans le constructeur BlockCrypt. Il attrape une exception sans message et affiche "null" à System.err. Plutôt que d'abandonner l'exécution — peut-être en lançant une exception du constructeur — vous continuez à naviguer.

Remplacer System.err.println(e.getMessage()) par e.printStackTrace() ou au moins System.err.println(e) devrait vous donner plus de détails. Ma conjecture est que ecipher.init() lève une exception parce que vous fournissez un IV de 32 bits au lieu de 64 bits.

+0

Merci d'avoir pris le temps de répondre. Si je m'assure que l'IV est 64 bits, le programme fonctionne parfaitement! Vous serez au générique quand j'aurai terminé mon projet d'expo-sciences. (Je ne sais pas ce que je peux faire d'autre pour vous remercier - je ne suis qu'une huitième élève.) – nsdel

0

Peut-être que regarder cela à the source for javax.crypto.Cipher est utile? Je ne pouvais pas vraiment comprendre, même trouver le message d'erreur dans la source. Bonne chance!

Questions connexes