2017-06-13 3 views
0

Ich denke, ich vermisse etwas, ich glaube, das Bild (in Bytes konvertiert) wird verschlüsselt, aber nicht entschlüsselt, wenn es auf der Client-Seite ankommt. Das Bild scheint die Überprüfung der RSA-Signatur zu bestehen, aber irgendwie kann es nicht angezeigt werden.Android rc4 Verschlüsselung

Client Side-Code:

public void aliceEncrypt(byte[] plaintext, byte[] sharedSecret) { 

    Cipher cipher; 
    byte[] encrypted = null; 
    try { 
     cipher = Cipher.getInstance("RC4"); 
     Key sk = new SecretKeySpec(sharedSecret, "RC4"); 
     cipher.init(Cipher.ENCRYPT_MODE, sk); 
     encrypted = cipher.doFinal(plaintext); 
     CipherOutputStream cos = new CipherOutputStream(socket.getOutputStream(), cipher); 
     ObjectOutputStream oos = new ObjectOutputStream(cos); 
     oos.writeObject(encrypted); 
     oos.flush(); 

    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IOException | InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } 
} 

Server Side-Code:

public byte[] bobDecrypt(byte[] sharedSecret) { 


    Cipher cipher = null; 
    byte[] bytes = null; 
    byte[] decrypted = null; 
    try { 
     cipher = Cipher.getInstance("RC4"); 
     Key sk = new SecretKeySpec(sharedSecret, "RC4"); 
     cipher.init(Cipher.DECRYPT_MODE, sk); 
     CipherInputStream cis = new CipherInputStream(socket.getInputStream(), cipher); 
     ObjectInputStream ois = new ObjectInputStream(cis); 
     bytes = (byte[])ois.readObject(); 
     decrypted = cipher.doFinal(bytes); 

    } catch (NoSuchAlgorithmException | NoSuchPaddingException | IOException | InvalidKeyException | ClassNotFoundException e) { 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } 
    return decrypted; 
} 
+1

Ich glaube nicht, dass diese für RC4 existieren, bitte korrigieren Sie mich, wenn ich falsch bin. RC4 ist eine Stromchiffre, keine Notwendigkeit zum Auffüllen. – Melo

+0

Ich habe das nicht verstanden, Sie schlagen vor, ich entferne cipher.doFinal()? Werden die Daten noch verschlüsselt? – Melo

+0

Ok du hast meine Verwirrung beseitigt, es funktioniert, danke Kumpel. Ich war mir nicht sicher, ob ich das cipher.doFinal weglassen kann. Sie können Ihre Antwort strukturieren und ich werde sie akzeptieren. – Melo

Antwort

1

CipherInputStream und CipherOutputStream sollen alle schweres Heben tun, so dass Sie sie nur mit einem initialisierten Cipher Instanz liefern und dann Verwenden Sie die Schreib- und Lese-Stream-Methoden. In den meisten Fällen können Sie diese wie mit Ein- und Ausgabeströmen schichten, aber es gibt eine Feinheit: Wenn eine Blockchiffre verwendet wird, gibt es keine gute Möglichkeit, dem CipherOutputStream zu signalisieren, dass er Cipher.doFinal() aufrufen muss. Der einzige unterstützte Weg besteht darin, die Methode close() aufzurufen. Diese close() Aufrufe propagieren zu anderen umschlossenen Streams, und in diesem Fall, wo ein Socket-Outputstream umhüllt ist, schließt es den Socket als Nebeneffekt. Dies kann durchaus akzeptabel sein, aber Sie müssen sich dessen bewusst sein. In diesem Fall, weil Sie eine Byte-orientierte Stream-Chiffre (RC4) verwenden, gibt es keine Auffüllung, so Cipher.doFinal() ist im Grunde ein No-Op sowieso (naja, es setzt den Chiffre-Zustand), so Aufruf flush() ist so gut wie Rufen close(). Der Code unten ist im Grunde Ihr Code geändert, um korrekt zu zeigen, wie Sie die verschiedenen Streams schichten und verwenden.

public void aliceEncrypt(byte[] plaintext, byte[] sharedSecret, Socket socket) { 

    try { 
     Cipher cipher = Cipher.getInstance("RC4/ECB/NoPadding"); 
     Key sk = new SecretKeySpec(sharedSecret, "RC4"); 
     cipher.init(Cipher.ENCRYPT_MODE, sk); 
     CipherOutputStream cos = new CipherOutputStream(socket.getOutputStream(), cipher); 
     ObjectOutputStream oos = new ObjectOutputStream(cos); 
     oos.writeObject(plaintext); 
     oos.close(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 


public byte[] bobDecrypt(byte[] sharedSecret, Socket socket) { 


    try { 
     Cipher cipher = Cipher.getInstance("RC4/ECB/NoPadding"); 
     Key sk = new SecretKeySpec(sharedSecret, "RC4"); 
     cipher.init(Cipher.DECRYPT_MODE, sk); 
     CipherInputStream cis = new CipherInputStream(socket.getInputStream(), cipher); 
     ObjectInputStream ois = new ObjectInputStream(cis); 
     byte[] bytes = (byte[]) ois.readObject(); 
     return bytes; 

    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
}