2011-05-19 21 views
5

He estado tratando de escribir un pequeño servidor de archivos. Llegué al punto en que la transferencia de archivos está bien, pero ahora que he intentado agregar encriptación están sucediendo cosas extrañas. Estoy tratando de usar flujos de entrada/salida de cifrado para enviar el archivo usando cifrado DES. El servidor parece haber transferido completamente el archivo, pero no puedo lograr que el cliente lo reciba correctamente.Java enviando archivo cifrado a través del socket

No importa qué tipo de archivo transfiero, el cliente nunca abandona el bucle que estoy usando para recibir el archivo. Aun así, he logrado recibir archivos .pdf y .doc, ninguno de los cuales parece tener ningún error, y se abren perfectamente. Sin embargo, cuando envío una imagen, parece que el final no se procesa correctamente. La imagen se abre, pero el final nunca se muestra, solo aparece un área gris.

Me imagino que estos problemas están relacionados, pero no sé cómo solucionarlos.

Aquí está el código que estoy usando para enviar el archivo en el servidor:

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
CipherOutputStream cipherOut = new CipherOutputStream(outToClient, cipher); 
byte[] fileBuffer = new byte[BUFFER_SIZE]; 
InputStream fileReader = new BufferedInputStream(new FileInputStream(aFile)); 
int bytesRead; 
while((bytesRead = fileReader.read(fileBuffer)) != EOF){ 
    cipherOut.write(fileBuffer, 0, bytesRead); 
} 
cipherOut.flush(); 

Y el código para recibirlo en el lado del cliente:

Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
cipher.init(Cipher.DECRYPT_MODE, serverPublicKey); 
CipherInputStream cipherIn = new CipherInputStream(inFromServer, cipher); 

byte[] fileBuffer = new byte[BUFFER_SIZE]; 
FileOutputStream fileWriter = new FileOutputStream(newFileName); 
int bytesRead; 
while((bytesRead = cipherIn.read(fileBuffer)) != EOF){ 
    fileWriter.write(fileBuffer, 0, bytesRead); 
} 
fileWriter.flush(); 
fileWriter.close(); 

Cualquier punteros en la derecha la dirección sería genial.

+4

Como nota al margen, DES es un algoritmo para ** cifrado simétrico **, es decir, no hay ningún concepto de ** clave pública ** (o clave privada) cuando se trata de DES. Los nombres 'publicKey' y' serverPublicKey' de sus variables son engañosos, ya que en realidad representan un ** secreto compartido **. –

+0

no cierra el lado del servidor de salida. Y es EOF -1 o 0 debería ser -1 –

Respuesta

2
while((bytesRead = cipherIn.read(fileBuffer)) != EOF){ 

es sólo va a seguir leyendo hasta que el número de 'BytesRead' le da EOF, pero eso no va a ocurrir porque no se está cerrando la toma de corriente (al menos no que yo pueda ver si su código) en el otro extremo.

veo

cipherOut.flush() ; 

pero eso no va a cerrar el zócalo. Si simplemente se está "cayendo fuera del alcance", no se cerrará hasta que el recolector de basura recolecte el objeto.

+0

Veo que aceptó esta respuesta, pero cerrar el socket no es necesario y esta no es realmente la mejor solución. – jedwards

+1

De acuerdo, pero la pregunta era, "¿qué no funciona?" no "cómo hacer esto, ¿verdad?" – Andrew

+0

@jdedwards Es necesario si el receptor lee EOS. Es posible evitar ambos a través de un prefijo de palabra de longitud o algún otro protocolo superpuesto. Pero dado el código de cliente existente, el cierre es necesario. – EJP

2

no cierra el lado del servidor CipherOutputStream

con el bloque Cyphers un rubor podría causar algunos bytes de no ser envían hasta que el bloque está vacío o se ejecuta un cierre que hará que el relleno entre en vigor y permitirá que el receptor encuentre el EOF

Cuestiones relacionadas