2011-12-26 65 views
-1

我正在尝试编写一个简单的应用程序,以便使用Java中的JCA和JCE加密和解密大块文本。使用JCA和JCE对Java中的文本块进行加密和解密

到目前为止加密部分作品,但解密时,它给了我以下异常:

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher 

这是我初始化两种加密算法,encCipher和decCipher的部分。

PBEKeySpec pbeKeySpec; 
PBEParameterSpec paramSpec; 
SecretKeyFactory keyFac; 
byte[] salt = {(byte) 0xc7, (byte) 0x73, (byte) 0x21, (byte) 0x8c, 
       (byte) 0x7e, (byte) 0xc8, (byte) 0xee, (byte) 0x99}; 
int count = 20; 
paramSpec = new PBEParameterSpec(salt, count); 

try { 
    pbeKeySpec = new PBEKeySpec("my_password".toCharArray(), salt, count); 
    SecretKey secretKey = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(pbeKeySpec); 

    encCipher = Cipher.getInstance(secretKey.getAlgorithm()); 
    encCipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec); 
    decCipher = Cipher.getInstance(secretKey.getAlgorithm()); 
    decCipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec); 

} catch (Exception ex) { 
    ex.printStackTrace(); 
} 

我没有使用Java密码体系结构的经验,我想知道我该如何解决这个错误。

异常发生在loadClients的decCipher.doFinal行。

private void saveClients() { 
    String plainText = ""; 
    String encText = ""; 
    Set<String> clients = my_clients.keySet(); 
     try { 
      PrintWriter out = new PrintWriter(new File(output_file)); 
      for (String client : clients) { 
       long client_time = my_clients.get(client); 
       plainText = client + " " + client_time; 

       encText = new String(encCipher.doFinal(plainText.getBytes())); 
       out.println(encText); 
      } 
      out.close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private void loadClients() { 
     BufferedReader in; 
     String line; 
     try { 
      in = new BufferedReader(new FileReader(output_file)); 
      while ((line = in.readLine()) != null) { 
       byte[] decBytes = decCipher.doFinal(line.getBytes()); 
       String decText = new String(decBytes); 
       String[] client_data = decText.split("[ ]"); 
       my_clients.put(client_data[0], Long.parseLong(client_data[1])); 
      } 
      in.close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
+0

错误出现在用于加密和解密的代码中。让我们看看这个代码。我尝试了以下代码,它按预期工作:by​​te [] text =“Hello world”.getBytes(“UTF-8”); byte [] encrypted = encCipher.doFinal(text); byte [] decrypted = decCipher.doFinal(encrypted); System.out.println(new String(decrypted,“UTF-8”)); – 2011-12-26 14:40:39

+0

我已经添加了用于加密和解密的功能。是否有可能是因为我使用BufferedReader读取而PrintWriter用于写入文件而不是OutputStream? – user852689 2011-12-26 15:21:18

回答

1

问题出在您将字节转换为字符串的事实。假设您的默认平台编码是ASCII。这意味着加密文本(字节128及以上)中包含的一半字节不表示有效字符。而且,你为每个加密文本写一行。所以,如果你的加密字节数组恰好包含一个换行字符,你实际上会写两行到作者,并试图逐一解密每一行,这将导致异常。

要么使用字节来存储和传输您的加密数据,要么使用像Base64这样的非有损算法将它们转换为字符串(这将确保将所有内容都转换为可打印字符)。 Apache commons-codec有一个Base64实现。

相关问题