2017-07-31 73 views
0

因此我决定扩展我在密码学方面的知识,但是我有以下代码来加密文件的内容并解密它。解密文件内容时会返回不同的字节

我的问题是,当我解密内容和比较两个字节数组我有(原始和解密的内容)我有两个不同的数组长度,甚至在内容。 你们中的任何人都可以发现我的代码中可能存在哪些错误?原始内容是一个基本的64位解码字节数组。

public class KeyStoreHelper { 

    public static byte[] decryptAES(FileInputStream fis, byte[] key) throws IOException { 

     CipherInputStream cin = null; 
     try { 

      byte[] keyBytes = getKeyBytes(key); 
      Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); 
      IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes); 
      aesCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); 

      byte[] buffer = new byte[1024]; 

      ByteArrayInputStream cipherIn = new ByteArrayInputStream(buffer); 
      ByteArrayOutputStream cipherOut = new ByteArrayOutputStream(); 
      cin = new CipherInputStream(cipherIn, aesCipher); 

      int length; 
      while ((length = fis.read(buffer)) != -1) { 
       cin.read(buffer, 0, length); 
       cipherOut.write(buffer); 
      } 

      return cipherOut.toByteArray(); 
     } catch (InvalidKeyException | NoSuchAlgorithmException 
       | NoSuchPaddingException e) { 
      throw new RuntimeException(e); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (cin != null) { 
       cin.close(); 
      } 
      if (fis != null) { 
       fis.close(); 
      } 
     } 
     return new byte[1]; 
    } 

    public static void encryptAES(FileOutputStream fos, byte[] plainText, byte[] key) throws IOException { 

     CipherOutputStream cos = null; 
     try { 
      byte[] keyBytes = getKeyBytes(key); 
      Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); 
      IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes); 
      aesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); 

      cos = new CipherOutputStream(fos, aesCipher); 
      cos.write(plainText); 
      cos.flush(); 

     } catch (InvalidKeyException | NoSuchAlgorithmException 
       | NoSuchPaddingException e) { 
      throw new RuntimeException(e); 
     } catch (InvalidAlgorithmParameterException e) { 
      e.printStackTrace(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (cos != null) { 
       cos.close(); 
      } 
      if (fos != null) { 
       fos.flush(); 
       fos.close(); 
      } 
     } 
    } 

    private static byte[] getKeyBytes(final byte[] key) throws Exception { 
     byte[] keyBytes = new byte[16]; 
     System.arraycopy(key, 0, keyBytes, 0, Math.min(key.length, keyBytes.length)); 
     return keyBytes; 
    } 
} 

含量为从服务器下载的文件:

原始字节[] = {48,-126,11,123,...},。长度= 2943

解密字节[ ] = {48,-126,11,123,...},.length = 3072(!)

为什么我有这个长度差异?

+1

您可以发布您加密的内容以及解密后得到的内容吗? –

+0

我刚刚那样做! – Karoly

+0

即3倍的缓冲区大小,请参阅我的答案。 –

回答

3

好像你正在处理的文件,但实际上你犯了一些错误:

  • 你不需要ByteArrayInputStream,如果你已经有了一个FileInputStream;
  • 您在写入CipherOutputStream时忽略了从输入流中读取的字节数;您忘记关闭CipherOutputStream

基本上你真的需要正确处理Java I/O流。

+0

感谢您的帮助,并指出我在代码中的错误。仔细考虑您的意见后,我设法修复了代码。它现在完美运行! – Karoly

+0

不客气,对不起,对于结束的一天snarky备注:) –

+0

耶稣不,你是绝对正确的。我在星期五晚上写了这段代码:在这里也是如此,但没有任何借口,因为我说你很好地指出了这些问题!这是一个耻辱,我不能投票两次:D – Karoly

相关问题