2017-10-03 6 views
0

私は大きなクライアント - サーバプログラムを持っています。ソケットからの読み取り/復号化時のjava.io.EOFException

しかし、暗号化されたパッケージを送信した場合、そのパッケージを受信して​​復号化しようとすると、java.io.EOFExceptionが返されます。

暗号化されていない方法(たとえばpingなど)を使用すると、完全に機能します。

クライアントコード(受信):

InputStream is = subChannel.getInputStream(); 
ObjectInputStream pre = new ObjectInputStream(is); 
ObjectInputStream ois; 
boolean crypt = (boolean) pre.readObject(); 

if (crypt) { 
    ois = new ObjectInputStream(SimpleAES.decryptInputStream(c.getAesKey(), is)); 
} else { 
    ois = new ObjectInputStream(is); 
} 

Response<? extends Serializable> res = (Response<? extends Serializable>) ois.readObject(); 
req.onResponse(res); 
is.close(); 

subChannel区切っ接続ソケットです。

私はこれがエラーではないという応答を得ることを知っています。

SimpleAES

private final static byte[] iv = new byte[16]; 
private static final String TRANSFORMATION = "AES/CBC/NoPadding"; 

public static CipherOutputStream cryptOutputStream(SecretKey key,OutputStream os) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException { 
     Cipher cipher = Cipher.getInstance(TRANSFORMATION); 
     IvParameterSpec ivspec = new IvParameterSpec(iv); 
     cipher.init(Cipher.ENCRYPT_MODE, key, ivspec); 
     CipherOutputStream out = new CipherOutputStream(os, cipher); 
     return out; 
} 

public static CipherInputStream decryptInputStream(SecretKey key,InputStream os) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException { 
     Cipher cipher = Cipher.getInstance(TRANSFORMATION); 
     IvParameterSpec ivspec = new IvParameterSpec(iv); 
     cipher.init(Cipher.DECRYPT_MODE, key, ivspec); 
     CipherInputStream out = new CipherInputStream(os, cipher); 
     return out; 
} 

Serverコード(送信):

OutputStream base; 
base = sock.getOutputStream(); 

ObjectOutputStream infoStream = new ObjectOutputStream(base); 

infoStream.writeObject(pack.isEncrypted()); 
ObjectOutputStream packageStream; 

if (pack.isEncrypted()) { 
    String tolken = pack.getClientTolken(); 
    Session s = getSession(tolken); 
    packageStream = new ObjectOutputStream(SimpleAES.cryptOutputStream(s.getAesKey(), base)); 
} 
else 
    packageStream = new ObjectOutputStream(base); 

packageStream.writeObject(pack); 
packageStream.flush(); 

if (pack instanceof Request) { 
    InputStream baseIn = sock.getInputStream(); 
    ObjectInputStream res; 

    if (pack.isEncrypted()) { 
     res = new ObjectInputStream(SimpleAES.decryptInputStream(getSession(pack.getClientTolken()).getAesKey(), baseIn)); 
    } else { 
     res = new ObjectInputStream(baseIn); 
    } 

    @SuppressWarnings("unchecked") 
    Response<? extends Serializable> response = (Response<? extends Serializable>) res.readObject(); 
    ((Request) pack).onResponse(response); 
    res.close(); 
} 

base.close(); 

私は、スタックトレースはあなたに大きな情報を与えるとは思わないが、ここにある:

Ping Response : 8ms 
[Client] Added TolkenRequest to Query 
[Client] Added RSARequest to Query 
[Client] Added AESKeyPack to Query 
[Client] Added ValidIdRequest to Query 
java.io.EOFException 
Fatal Error Exit 
    at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source) 
    at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source) 
    at java.io.ObjectInputStream.readShort(Unknown Source) 
    at java.io.ObjectStreamClass.readNonProxy(Unknown Source) 
    at java.io.ObjectInputStream.readClassDescriptor(Unknown Source) 
    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) 
    at java.io.ObjectInputStream.readClassDesc(Unknown Source) 
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source) 
    at java.io.ObjectInputStream.readSerialData(Unknown Source) 
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.readObject(Unknown Source) 
    at com.niton.tele.core.network.client.ClientListenerThread.run(ClientListenerThread.java:104) 

ClientListenerThread.java:104はこの行です。レスポンスres =(レスポンス)ois.readObject();

+0

これはあなたの問題とは関係ありませんが、IVを正しく使用する必要があります。暗号化するときに予測できない(ランダムな)値に設定し、暗号化する必要はありません(暗号化する必要はありません)。解読するとき。 IVをそのまま使用することは安全とはみなされません。 –

+0

私は知っています。これはテストのためだけでした。なぜなら、そのallways 0000000私はTodを必要としない場合 – Niton

+0

私はストリームの2つの異なる種類を分けることを試みるだろう:暗号化されたストリームを解読する簡単な方法を書いて、シリアル化されたオブジェクトを介して送信します。ちょうど私の2セント。 –

答えて

1

異なるバッファリングされたストリームを同じソケットに混在させることはできません。彼らは互いにデータを盗みます。ソケットの寿命の間、とObjectOutputStreamの1つを使用してこれを再設計して書き直す必要があります。

おそらくSealedObjectをお探しですか?

関連する問題