2016-12-17 5 views
0

私のソフトウェアは、解読中にStreamCorruptedExceptionを発生させました: 私の暗号はAES/CBC/PKCS5Paddingで、私の鍵はPBKey Derivationメソッドで得られます。 AES128キー。シリアル化されたオブジェクトの復号化(および他のバイトフィールド)中のStreamCorruptedException

私の目標は、このようにして形成されたファイルを取得することです:

(私は読みやすさを向上させるために、例外管理コードを削除します) マイサイファコード:

char[] password = passwordString.toCharArray(); 

    SecureRandom random = new SecureRandom(); 
    byte salt[] = new byte[SALT_BYTES]; 
    random.nextBytes(salt); 

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); 

    KeySpec keySpec = new PBEKeySpec(password, salt, ITERATION, AES_KEY_BITS); 

    SecretKey tmp = factory.generateSecret(keySpec); 

    SecretKey secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); 

    Cipher cipher = Cipher.getInstance("AES/CFB/PKCS5Padding"); 

    cipher.init(Cipher.ENCRYPT_MODE, secretKey); 

    FileOutputStream fout = null; 
    ObjectOutputStream objOut = null; 


     fout = new FileOutputStream(PRIVATE_RING_FILENAME); 

     fout.write(salt); 

     byte[] ivN = cipher.getIV(); 
     fout.write(ivN); 

     CipherOutputStream cos = new CipherOutputStream(fout, cipher); 
     objOut = new ObjectOutputStream(cos); 

     PrivateKeyRing prvKeyRing = new PrivateKeyRing(); 
     SealedObject sealedObject = new SealedObject(prvKeyRing, cipher); 
     objOut.writeObject(sealedObject); 

     fout.close(); 
     objOut.close(); 
     cos.close(); 

し、それを問題なく動作します。

マイ解読コード:

char[] password = passwordString.toCharArray(); 

    File file = new File(PRIVATE_RING_FILENAME); 
    FileInputStream fin = new FileInputStream(file); 


    Cipher cipher = Cipher.getInstance("AES/CFB/PKCS5Padding"); 


    byte[] salt = new byte[SALT_BYTES]; 

    fin.read(salt); 


    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); 


    KeySpec keySpec = new PBEKeySpec(password, salt, ITERATION, AES_KEY_BITS); 

    SecretKey = factory.generateSecret(keySpec); 

    SecretKey secretKey = new SecretKeySpec(tmp.getEncoded(), "AES"); 


     byte[] ivN = new byte[AES_BYTES]; 
     fin.read(ivN, 0, AES_BYTES); 

     cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(ivN)); 

    CipherInputStream cis = new CipherInputStream(fin, cipher); 
    ObjectInputStream objIn; 
    PrivateKeyRing prvKeyRing = null; 
    SealedObject sealedObject = null; 
    objIn = new ObjectInputStream(cis); 

    sealedObject = (SealedObject) objIn.readObject(); 
    prvKeyRing = (PrivateKeyRing) sealedObject.getObject(cipher); 

     objIn.close(); 
     fin.close(); 
     cis.close(); 

しかしStreamCorruptedException:無効なストリームヘッダ:システムは実行時に73720019が発生します。

objIn = new ObjectInputStream(cis); 

私はすべての作品を暗号せずにオブジェクトを書き込むしよう。 あなたはどう思いますか? 複数のシリアライズされたオブジェクトを書き込もうとしたときにいくつかの問題について読んだことがありますが、これは当てはまりません。

+1

なぜあなたは2回暗号化と復号化を行っていますか? – EJP

+1

一方、あなたは間違った順序で出力ストリームを終了しています。 「最奥」を最初に閉じます。理想的には、手動で閉じるのではなく、try-with-resourcesステートメントを使用します。次に、 'InputStream.read'の結果を無視しています。期待どおりのバイト数を読み込んでいないかもしれません。あなたは 'ivN'と'塩 'が期待通りだと確認しましたか? –

+0

また、 'AES_BYTES'とは何ですか、あなたは' ivn.length'と同じであることを確認しましたか? –

答えて

1

これは、同じ暗号で2回暗号化と復号化を行うためです。オブジェクトは最初に暗号で密封され、暗号出力ストリームに書き込まれます。暗号は、オブジェクトを密封した結果の状態になります。これは、初期状態の暗号で復号化できるファイルを生成しません。最初にオブジェクトのシールを解除してストリームから読み取る必要がありますが、これは不可能です。暗号ストリームまたは封印されたオブジェクトを取り除く。

+0

封印されたオブジェクトを使用せずに作成する必要がありますか? 私はオブジェクトを直接書く必要がありますか? –

+0

修正。暗号ストリーム*または*封印されたオブジェクトのいずれか*が必要です。両方ではありません。 – EJP

関連する問題