2017-07-31 28 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

相關問題