# [Netzwerk/Sicherheit] Hybrid-Kryptosystem



## despikyxd (30. Jan 2011)

[NET/SICHERHEIT] hybrides Kryptosystem mit RSA und AES

ich denke ich muss den interessierten die funktionsweise von RSA und AES nicht erklären und kann gleich mit dem code durchstarten

nach langem suchen und probieren habe ich nun ein hybrides krypto-system entwickelt um befehle und daten gesichert zu übertragen
die verwendung für RAW daten ist zwar nicht implementiert lässt sich aber einfach mit zwei zusätzlichen methoden realisieren ... zur zeit sind die zusendenen daten dem limit unterlegen das diese durch ein String-Objekt darstellbar sein müssen um zum empfangen die readLine() methode des BufferedReader nutzen zu können
die daten selbst werden als HEX-daten übertragen um eine leichte rückkonvertierung in byte zu ermöglichen

das system stütz sich dabei auf 3 klassen

1. synccrypt.java - stellt die hauptklasse da ... über sie wird der AES-schlüssel erstellt *mit einer static-methode* und die ver- und entschlüsselung bewerkstelligt
2. asynccrypt.java - klasse für das RSA-system mit schlüsselerstellung, -austausch und austausch des AES-schlüssels
3. tools.java - helfer-klasse ... enthält lediglich 2 methoden zur konvertierung zwischen String und byte[] *könnte auch in synccrypt integriert werden*

source

synccrypt.java

```
import java.io.*;
import java.security.*;
import javax.crypto.*;
class synccrypt
{
	private BufferedReader in=null;
	private PrintStream out=null;
	private Cipher ecip=null;
	private Cipher dcip=null;
	private SecretKey sk=null;
	public synccrypt() { }
	//konstruktor mit übergabe der in- und outputstreams und des AES-schlüssels
	public synccrypt(BufferedReader in, PrintStream out, SecretKey sk) { this.in=in; this.out=out; this.sk=sk; }
	//init-funktion zur initialisierung der cipher
	public void init() throws Exception
	{
		ecip=Cipher.getInstance("AES");
		ecip.init(Cipher.ENCRYPT_MODE, sk);
		dcip=Cipher.getInstance("AES");
		dcip.init(Cipher.DECRYPT_MODE, sk);
	}
	//static-methode zur erzeugung des AES-schlüssels
	public static SecretKey genKey() throws Exception
	{
		KeyGenerator kg=KeyGenerator.getInstance("AES");
		kg.init(new SecureRandom());
		return kg.generateKey();
	}
	//sende- und empfangsmethoden
	public void sendMsg(String msg) throws Exception
	{
		byte[] input=msg.getBytes();
		byte[] output=crypt(input, ecip);
		String send=tools.hex(output);
		out.println(send);
	}
	public String recieveMsg() throws Exception
	{
		String line=new String("");
		while(true)
		{
			line=in.readLine();
			if(line==null)
				return (new String(""));
			if(!line.equals(""))
				break;
		}
		byte[] input=tools.dehex(line);
		byte[] ret=crypt(input, dcip);
		return (new String(ret));
	}
	//private crypto-methode für ver- und entschlüsselung
	private byte[] crypt(byte[] input, Cipher cip) throws Exception
	{
		ByteArrayInputStream bais=new ByteArrayInputStream(input);
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		int bs=cip.getBlockSize();
		int os=cip.getOutputSize(bs);
		byte[] inb=new byte[bs];
		byte[] outb=new byte[os];
		int inl=0;
		boolean fin=false;
		while(!fin)
		{
			inl=bais.read(inb);
			if(inl==bs)
			{
				int outl=cip.update(inb, 0, bs, outb);
				baos.write(outb, 0, outl);
			}
			else
				fin=true;
		}
		if(inl>0)
			outb=cip.doFinal(inb, 0, inl);
		else
			outb=cip.doFinal();
		baos.write(outb);
		return (baos.toByteArray());
	}
}
```

asynccrypt.java

```
import java.math.*;
import java.io.*;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import javax.crypto.*;
class asynccrypt
{
	BufferedReader in=null;
	PrintStream out=null;
	PublicKey pub=null;
	PrivateKey priv=null;
	public asynccrypt() { }
	//konstruktor mit übergabe der in- und outputstreams
	public asynccrypt(BufferedReader in, PrintStream out) { this.in=in; this.out=out; }
	//methode zur generierung des schlüsselpaars
	public void genKeyPair() throws Exception
	{
		KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
		SecureRandom sr=new SecureRandom();
		kpg.initialize(1024, sr);
		KeyPair kp=kpg.generateKeyPair();
		pub=kp.getPublic();
		priv=kp.getPrivate();
	}
	//methoden zum senden und empfangen des public-keys
	public void sendPublicKey() throws Exception
	{
		RSAPublicKey pk=(RSAPublicKey)pub;
		BigInteger mod=pk.getModulus();
		out.println(mod.toString(16));
	}
	public void recievePublicKey() throws Exception
	{
		String line=new String("");
		while(true)
		{
			line=in.readLine();
			if(!line.equals(""))
				break;
		}
		BigInteger exp=new BigInteger("65537");
		BigInteger mod=new BigInteger(line, 16);
		RSAPublicKeySpec ks=new RSAPublicKeySpec(mod, exp);
		KeyFactory kf=KeyFactory.getInstance("RSA");
		pub=kf.generatePublic(ks);
	}
	//methoden zum senden und empfangen des AES-schlüssels
	public void sendSyncKey(SecretKey sk) throws Exception
	{
		Cipher c=Cipher.getInstance("RSA");
		c.init(Cipher.WRAP_MODE, pub);
		byte[] wk=c.wrap(sk);
		out.println(tools.hex(wk));
	}
	public SecretKey recieveSyncKey() throws Exception
	{
		String line=new String("");
		while(true)
		{
			line=in.readLine();
			if(!line.equals(""))
				break;
		}
		byte[] wk=tools.dehex(line);
		Cipher c=Cipher.getInstance("RSA");
		c.init(Cipher.UNWRAP_MODE, priv);
		SecretKey sk=(SecretKey)c.unwrap(wk, "AES", Cipher.SECRET_KEY);
		return sk;
	}
}
```

helfer-klasse tools.java

```
public class tools
{
	public static String hex(byte[] input) throws Exception
	{
		StringBuffer sb=new StringBuffer(input.length*2);
		for(int i=0; i<input.length; i++)
		{
			int v=input[i]&0xFF;
			if(v<16)
				sb.append("0");
			sb.append(Integer.toHexString(v));
		}
		return sb.toString().toUpperCase();
	}
	public static byte[] dehex(String input) throws Exception
	{
		byte[] ret=new byte[input.length()/2];
		for(int i=0; i<ret.length; i++)
		{
			int index=i*2;
			int v=Integer.parseInt(input.substring(index, index+2), 16);
			ret[i]=(byte)v;
		}
		return ret;
	}
}
```

wie ihr seht ist das ganze eher simpel gehalten und sieht für viele sicher sehr schrecklich aus
ich habe mir halt diesen programmierstil angewöhnt und werde auch weiter so schreiben da ich bei einigen stilen nicht wirklich den unterschied sehe

beispiel welches für mich eher verwirrend ist als irgendwie logisch

```
public void method() {
	//code
}
```
meine schreibweise

```
public void method()
{
	//code
}
```

ich persönlich finde meine variante deutlich übersichtlicher und leichter zuordbar ... aber naja ...

ich habe zur demonstration auch ein beispiel programmiert
dies beinhaltet einen server , einen clienten und einen sniffer der zwischen beiden die daten als RAW ausgibt

SERVER
sserver.java

```
import java.io.*;
import java.net.*;
public class sserver
{
	public static void main(String[] args) { new sserver(); }
	public sserver()
	{
		ServerSocket ss=null;
		try { ss=new ServerSocket(7459); }
		catch(Exception e) { e.printStackTrace(); System.exit(1); }
		while(true)
		{
			try
			{
				Socket cs=ss.accept();
				(new sclient(cs)).start();
			}
			catch(Exception e) { }
		}
	}
}
```

sclient.java

```
import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
class sclient extends Thread
{
	Socket cs=null;
	public sclient() { }
	public sclient(Socket cs) { this.cs=cs; }
	public void run()
	{
		InputStream in=null;
		OutputStream out=null;
		try { in=cs.getInputStream(); out=cs.getOutputStream(); }
		catch(Exception e) { try { cs.close(); } catch(Exception ex) { } }
		try
		{
			BufferedReader bin=new BufferedReader(new InputStreamReader(in));
			PrintStream pout=new PrintStream(out, true);
			asynccrypt ac=new asynccrypt(bin, pout);
			ac.genKeyPair();
			ac.sendPublicKey();
			SecretKey sk=ac.recieveSyncKey();
			synccrypt sc=new synccrypt(bin, pout, sk);
			sc.init();
			String line=new String("");
			while(true)
			{
				try { line=sc.recieveMsg(); } catch(Exception ex) { break; }
				if(!line.equals(""))
				{
					System.out.println(line);
					sc.sendMsg(line);
				}
			}
			in.close();
			out.close();
			cs.close();
		}
		catch(Exception e) { }
	}
}
```


CLIENT
client.java

```
import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
public class client
{
	public static void main(String[] args) { new client(); }
	public client()
	{
		Socket cs=null;
		InputStream in=null;
		OutputStream out=null;
		try { cs=new Socket("127.0.0.1", 7460); }
		catch(Exception e) { e.printStackTrace(); System.exit(1); }
		try { in=cs.getInputStream(); out=cs.getOutputStream(); }
		catch(Exception e) { e.printStackTrace(); System.exit(1); }
		BufferedReader cin=new BufferedReader(new InputStreamReader(System.in));
		BufferedReader bin=new BufferedReader(new InputStreamReader(in));
		PrintStream pout=new PrintStream(out);
		asynccrypt ac=new asynccrypt(bin, pout);
		try { ac.recievePublicKey(); }
		catch(Exception e) { e.printStackTrace(); System.exit(1); }
		SecretKey sk=null;
		try { sk=synccrypt.genKey(); ac.sendSyncKey(sk); }
		catch(Exception e) { e.printStackTrace(); System.exit(1); }
		synccrypt sc=new synccrypt(bin, pout, sk);
		try { sc.init(); } catch(Exception e) { }
		(new clientreader(sc)).start();
		String line=new String("");
		while(true)
		{
			try
			{
				line=cin.readLine();
				if(line.equals("exit"))
					break;
				if(!line.equals(""))
					sc.sendMsg(line);
			}
			catch(Exception e) { break; }
		}
		try
		{
			in.close();
			out.close();
			cs.close();
		}
		catch(Exception e) { }
		System.exit(0);
	}
}
```

clientreader.java

```
import java.io.*;
class clientreader extends Thread
{
	synccrypt sc=null;
	public clientreader() { }
	public clientreader(synccrypt sc) { this.sc=sc; }
	public void run()
	{
		String line=new String("");
		while(true)
		{
			try
			{
				line=sc.recieveMsg();
				if(line==null)
					break;
				if(!line.equals(""))
					System.out.println(line);
			}
			catch(Exception e) { break; }
		}
	}
}
```


SNIFFER
sniffer.java

```
import java.io.*;
import java.net.*;
public class sniffer
{
	public static void main(String[] args) throws Exception { new sniffer(); }
	public sniffer() throws Exception
	{
		ServerSocket ss=new ServerSocket(7460);
		while(true)
		{
			Socket cs=ss.accept();
			InputStream in=cs.getInputStream();
			OutputStream out=cs.getOutputStream();
			Socket cc=new Socket("127.0.0.1", 7459);
			InputStream cin=cc.getInputStream();
			OutputStream cout=cc.getOutputStream();
			(new snifflog(in, cout)).start();
			(new snifflog(cin, out)).start();
		}
	}
}

class snifflog extends Thread
{
	InputStream in=null;
	OutputStream out=null;
	public snifflog() { }
	public snifflog(InputStream in, OutputStream out) { this.in=in; this.out=out; }
	public void run()
	{
		int read=0;
		byte[] buf=new byte[8192];
		while(true)
		{
			try
			{
				while((read=in.read(buf))!=-1)
				{
					if(read==0)
						continue;
					System.out.write(buf, 0, read);
					out.write(buf, 0, read);
				}
			}
			catch(Exception e) { }
		}
	}
}
```

ich werde versuchen für den gesamten code support zu leisten und bei fragen , verbesserungsvorschlägen und vor allem kritiken zu reagieren und zu antworten

alles in allem denke ich doch das ich hier einen sehr interessanten thread gestartet habe und das es einigen bei der netcode-entwicklung helfen wird

greedz ... SPiKEe


----------



## XHelp (30. Jan 2011)

Hab mir zwar den Code noch nicht angeguckt, aber aus dem Text erkenne ich keine Frage. Deswegen ist der Thread wohl eher bei "Codeschnipsel u. Projekte" besser aufgehoben. Ein Mod sollte es mal verschieben.


----------



## madboy (30. Jan 2011)

Ein paar kleine Verbesserungen/Fragen hätte ich: 

1. Was wäre ein Anwendungsfall für deinen Code? Irgendwie will mir spontan nix einfallen.
2. Warum machst du erst einen hex-String aus den zu versendenden Bytes? Das bläht den Netzwerktraffic unnötig auf.
3. Klassen schreibt man groß und CamelCase, das hat nix mit dem Stil zu tun (wie öffnende geschweifte Klammern in neuer oder gleicher Zeile) 
4. 
	
	
	
	





```
catch(Exception e) { }
```
 == seeehr böse

EDIT: 5. Wenn du anderen beim Entwickeln helfen willst, solltest du den Code auch kommentieren. Sonst sind diejenigen die Hilfe benötigen vom Thema als auch von deinem Code überfordert


----------



## despikyxd (31. Jan 2011)

@XHelp
gut .. da hast du recht ...
aber ich bin sehr selten hier auf java-forum.org und bin daher mit den gewohnheiten hier nich so vertraut
bin halt eher bei tutorials.de inner java sektion ... und da postet man auch solche codeschnipsel einfach mal mit rein ...
werd ich mir aber fürs nächste mal merken und bitte auch selbst hiermit um verschiebung des threads

@madboy
1. z.B. eine eigene verschlüsselung ... natürlich kann man auch andere verfahren nehmen *wie SSL oder ähnliches*
aber aus genau aus diesem grund habe ich es geschrieben und hier gepostet ... um eben eine weitere alternative zu geben ... ich wollte halt kein SSL verwenden weil ich dann so einiges hätte anders schreiben müssen und das ganze dann auch noch in dem jar das ich dann verteile mitgeben für diejenigen die die nötigen files eben nicht haben ... was dann aber meine distribution unnötigt aufbläht ...
2. weil das hier für die einfachheit zur verwendung mit BufferedReader und PrintStream gedacht ist ... auf dierekter byte-eben hätte sich ein größerer auswand ergeben der sich für meine zwecke nicht lohnt ... sicher wird der traffic verdoppelt da für 1 byte 2 hex-zeichen verwendet werden die halt dann eben 2 byte traffic statt 1 erzeugen ... von daher völlig richtiger einwand ... aber für meine zwecke zu kompliziert ...
3. genau so eine antwort habe ich erwartet und sage hier ganz klar : ich halte mich mit meinem persönlichen stil nicht immer an die >EMPFOHLENEN< schreibweisen wie klassen KapitalCase , static-variablien UPPERCASE , methoden camelCase usw ...
es ist halt nur eine empfehlung der halt ein großteil der breiten masse folgt ... ist aber keine festgeschrieben pflicht ...
von daher : wer meine code verwendet muss damit halt zurecht kommen und mich nich auch noch dazu auffordern mich umzugewöhnen
ich versuche mitlerweile schon mich dem "normalen" stil anzunähern ... aber achte jetzt nicht explizit darauf wenn ichs mal nicht mache ...
4. dieses stück code findet sich nur in sserver.java wieder ... und dient lediglich dazu keine nervigen ausgaben und overhead zu erzeugen wenn mal eine verbindung fehlschlägt ...
die test-klassen sind ja auch nur zum testen ... die hauptklassen *also die krypto-klassen* sind halt auch der einfachheit halber nur mit throws Exception deklariert und müssen dann vom aufrufer abgefangen werden ... eine explizite auflistung der möglichen exceptions oder gar ein exception-handling wird aus bestimmten grund verwendet : wenn in den klassen ein exception handling durchgeführt werden würde würde der aufrufer 1. nichts davon mitbekommen und müsste 2. z.B. mit return boolean dazu angeregt werden eine standard-aktion bei fehlschlag auszuführen ... so kann man aber dann selbst im aufrufer das exception handlich vornehmen ...
also sei nich so streng mit dieser einen zeile ... das sind halt nur TEST-klassen ... wenn du sowas selbst implementierst kannst du an dieser stelle gerne logging oder anderen overhead erzeugen ... hindert dich ja keiner dran ...
natürlich ist sowas für einen produktiven einsatz wichtig und nützlich .. aber für eine test-klasse die nur prüfen soll ob es überhaupt funktioniert kann man darauf verzichten
5. hab ich ... die notwendigen kommentare die die funktionsweise der methoden beschreiben sind da ... was dann an code in den methoden steht sollte man wenn man ahnung von diesem thema hat auch ohne kommentare verstehen da ich den code auch bewusst nur für solche leute gepostet habe ...
als einstiegs-code für einen auf diesem gebiet unerfahrenen ist es einfach zu kompliziert ...
solche leute sollte einfache beispiele aus z.B. der java-insel mit DES und so nehmen ...
wenn man mit RSA und AES arbeiten will setze ich bei diesem code vorraus das man sich über die arbeitsweise im klaren ist und sich halbwegs ohne code vorstellen kann was man braucht ... darum finde ich jetzt diese forderung nach kommentierung ein wenig zu überspitz ... wenn man keine ahnung vom grundlegenden funktionsprinzip hat sollte man nicht versuchen durch kommentare sich wissen darüber anzueignen ... dafür sind tutorials da ...


----------



## despikyxd (2. Feb 2011)

*thread push*


----------



## Tomate_Salat (2. Feb 2011)

despikyxd hat gesagt.:


> 3. genau so eine antwort habe ich erwartet und sage hier ganz klar : ich halte mich mit meinem persönlichen stil



Ich denke ich bin nicht der einzigste: ich würde deinen Code so niemals verwenden. Schon alleine, weil ich probleme hätte, damit zu arbeiten. Zudem: Machst du das beruflich? Ich schätze mal nein: diese Konventionen gibt es nicht einfach so! (Ich hoffe doch) Alle Betrieben orientieren sich an geltenden Konventionen (mit minimalen abweichungen). Viel Spaß beim umgewöhnen, wenn du jemals beruflich damit arbeiten wirst.


----------



## despikyxd (3. Feb 2011)

ich liebe solche posts ...
erklär mir bitte erstmal konkret WAS dich darin hindert mit dem code zu arbeiten ...
fehlende comments > überflüssig weil sich die funktionsweise aus dem code ergibt ... wer unbedingt noch mit kilometerlangen comments drumrum reden will ist für mich der größere depp von uns beiden ... denn schon immer galt : wenn du aus dem code nicht rauslesen kannst was er macht musst du noch ne menge üben ...
nicht konventions-gerechte schreibweise und bezeichnung > völlig egal was für namen ich vergebe und wie ich sie schreibe ... manchmal reichen 2 oder 3 buchstaben für eine bezeichnung aus die ausgschrieben 15 - 20 zeichen lang wäre ...
und erlich ... ne dritte sache fällt mir noch nicht mal ein was ich angeblich FALSCH machen soll ... ich mach es nur ANDERST ...

also gewöhn du dir erstmal das herziehen über andere ab die sich nicht an irgendwelche ungeschriebenen gesetze halten bevor ich mir angewöhnen soll mich an diese zu halten ... weil so seh ich das ganze ...
mein code funktioniert ... und macht genau das was er soll ... wer ein problem hat sich diese funktionsweise dierekt ausm code rauszulesen und dafür lange comments braucht sollte doch noch einen blick in die api-docs werfen ...
und wer sich dazu noch an der schreibweise stört ... na dem is echt nich mehr zu helfen ... aber naja .. jedem das seine ... mach du ma ruhig deine aufgeblähten source-files weiter ... ich halt da lieber alles so knapp wie möglich *wobei korrektes einrücken nur die unterteilung in einzelne blöcke erleichtet und eigentlich nicht notwendig wäre*


----------



## HoaX (3. Feb 2011)

Es redet ja keiner von Gesetzen, aber es gibt Richtlinien an die sich jeder Javaprogammierer halten sollte, damit es möglichst einheitlich ist. Und in der Zeit wo man deinen Code korrigiert könnte man das ganze auch selber und in schön machen.

Natürlich fehlen Kommentare. Dein Argument mit "ergibt sich aus dem Code" zählt nicht. Wenn man genug Zeit investiert, dann kann man jeden Code auch ohne Kommentare verstehen. Dir fällt das momentan leicht deinen Code nachzuvollziehen, da du ihn ja selbst geschrieben hast. Jemand anderes kennt deinen Code nicht, da helfen Kommentare nunmal. Und wer will schon ne leere Javadoc?

Nächster Kritikpunkt: Bei dir kann nirgends ein Chaining-Modus angegeben werden.

Zu String#getBytes() möchte ich nicht viel sagen: Lies mal die Javadoc!

Und zum Schluss finde ich den Aufbau, bzw das was ich davon erkennen konnte suboptimal. Besser wären Klassen welche InputStream und OutputStream implementieren. Die Verschlüsselung arbeitet eh auf Byte-Ebene, warum selbst eine fehlerhafte Konvertierung basteln? Lieber direkt Bytes nehmen und dann den verschlüsselten Stream an einen PrintStream geben. Hollala, das gibts ja schon: javax.crypto.CipherInputStream und javax.crypto.CipherOutputStream

Beliebt nurnoch der Schlüsseltausch offen, und man hat alles in schön.


----------



## Tomate_Salat (3. Feb 2011)

despikyxd hat gesagt.:


> erklär mir bitte erstmal konkret WAS dich darin hindert mit dem code zu arbeiten ...


Es reicht schon vollkommen aus, dass du dich nicht an die Konventionen hälst



> nicht konventions-gerechte schreibweise und bezeichnung > völlig egal was für namen ich vergebe und wie ich sie schreibe [...] ich mach es nur ANDERST ...


Entwickle mal im Team und du wirst sehen, wie egal Konventionen sind



> also gewöhn du dir erstmal das herziehen über andere ab die sich nicht an irgendwelche ungeschriebenen gesetze


Wenn du nicht mit konstruktiver Kritik umgehen kannst, nicht mein Problem. Schreib von mir aus weiter deinen Code, iwann wirst du merken, was du davon hast.

Zum Abschluss: Komm mal wieder runter, ist ja unglaublich wie du reagierst! Lerne mit dieser Art Kritik klar zu kommen, denn wenn du hier Hilfe suchst und Sourcecode beilegst, wird man dich immer wieder darauf ansprechen.


----------



## XHelp (3. Feb 2011)

despikyxd hat gesagt.:


> fehlende comments > überflüssig weil sich die funktionsweise aus dem code ergibt ... wer unbedingt noch mit kilometerlangen comments drumrum reden will ist für mich der größere depp von uns beiden ... denn schon immer galt : wenn du aus dem code nicht rauslesen kannst was er macht musst du noch ne menge üben ...


Eigentlich heißt es, ein guter Code ist ein Code, der keine Kommentare braucht. Wenn dein Code offensichtlich welche braucht. Du hast einfach nur eine falsche Schlussfolgerung gezogen


> nicht konventions-gerechte schreibweise und bezeichnung > völlig egal was für namen ich vergebe und wie ich sie schreibe ... manchmal reichen 2 oder 3 buchstaben für eine bezeichnung aus die ausgschrieben 15 - 20 zeichen lang wäre ...
> und erlich ... ne dritte sache fällt mir noch nicht mal ein was ich angeblich FALSCH machen soll ... ich mach es nur ANDERST ...


Ok, ist deine Meinung. Dann musst du aber damit leben, dass sich keiner für den Code interessiert, und das Thema nicht pushen.


----------



## despikyxd (3. Feb 2011)

HoaX hat gesagt.:


> Besser wären Klassen welche InputStream und OutputStream implementieren. Die Verschlüsselung arbeitet eh auf Byte-Ebene, warum selbst eine fehlerhafte Konvertierung basteln? Lieber direkt Bytes nehmen und dann den verschlüsselten Stream an einen PrintStream geben. Hollala, das gibts ja schon: javax.crypto.CipherInputStream und javax.crypto.CipherOutputStream



hmm ... ja gerne ... nur dann bau mir mal n cipherstream der nich erstmal zwischen bufferd und erst sendet wenn er einen block fertig hat ...
ich habs ja auch erstmal so probiert ...

folgend

PrintStream(CipherOutputStream(socket.OutputStream))
BufferedReader(InputStreamReader(CipherInputStream(socket.InputStream)))

hat ja auch funktioniert ... problem war nur das ich erstmal ordenlich was an daten in die printstream schreiben musste bevor er anfing die ersten daten überhaupt zu senden ...
und das mit füll-bytes zu kompensieren erzeugt auch nur overhead ...

darum habe ich bewusst diesen umweg gewählt um dieses buffering zu umgehen ...
wenn du mir ne möglichkeit zeigst dieses buffering anders zu umgehen würde ich das gerne sehen

und thread-push ist zwar laut foren-regeln nich gestattet ... aber mal erlich : ich bin nich der einzige ... also lasst die kirche im dorf


----------



## Tomate_Salat (3. Feb 2011)

despikyxd hat gesagt.:


> und thread-push ist zwar laut foren-regeln nich gestattet ... aber mal erlich : ich bin nich der einzige ... also lasst die kirche im dorf



deswegen ist es weniger schlimm? :noe:
Achte mal ein wenig darauf wie du dich hier im Forum gibst. Anonym und Unverschämt! Nach dem Satz gehört der Thread eigentl. geclosed.


----------



## HoaX (3. Feb 2011)

despikyxd hat gesagt.:


> ...
> PrintStream(CipherOutputStream(socket.OutputStream))
> BufferedReader(InputStreamReader(CipherInputStream(socket.InputStream)))
> 
> ...


CipherOutputStream#flush() sollte eigentlich gewünschtes machen. (nicht getestet)



despikyxd hat gesagt.:


> und thread-push ist zwar laut foren-regeln nich gestattet ... aber mal erlich : ich bin nich der einzige ... also lasst die kirche im dorf


Na klar. Forenregeln gelesen, recherchiert dass es andere auch machen, aber im falschen Forum posten weil man zu selten hier ist und es nicht wusste ...

AMEN!

Edith sagt: Was du zum Senden/Puffern und dem Warum geschrieben hast wäre keiner Doku im Code würdig gewesen? Denk mal drüber nach.


----------



## despikyxd (6. Feb 2011)

HoaX hat gesagt.:


> CipherOutputStream.flush() sollte eigentlich gewünschtes machen. (nicht getestet)


leider nein ... das waren ja auch meine ersten überlegungen bei meinen ersten experimenten mit java und verschlüsselungen vor gut 3 jahren ... schade das sich bis jetzt nichts geändert hat
mein vermutung geht soweit *ohne jetzt in den source-files von CipherOutputStream oder den drunterliegenden streams nachgelesen zu haben* das flush zwar seine arbeit verrichtet ... nämlich die im output-buffer befindlichen daten zu senden ... aber die methode nicht soweit geht die im input-buffer befindlichen daten durch den cipher zu jagen und dann den output erst zu flushen ... ich gehe hier also von einem grundlegenden konzeptions-fehler dieser klasse aus ... kann aber auch sein das ich mich irre und es so erdacht ist um fehler zu vermeiden ... analog zu meinen konstrukten um genau diesen fehler zu umgehen

Edit : Was du zum Senden/Puffern und dem Warum du sowas geschrieben hast wäre keiner Doku im Code würdig gewesen?[/QUOTE]
erlich gesagt : ich habe es absichtlich nicht kommentiert da sonst fragen/meinungen gekommen wären wie : nutz doch CipherOutputStream.flush() oder : implementier es doch selber ...
ne ... da warte ich dann lieber auf die dierekte frage warum ich da sowas zusammen zimmere und erkläre dann das problem lieber in einem stück ...


----------



## despikyxd (11. Mrz 2011)

mal als kleines update ...
habe die synccrypt.java mal erweitert um auch dierekt binäre daten versenden zu können ... funktionen dazu


```
public void sendBinaryMsg(byte[] input) throws Exception
    {
        byte[] output=crypt(input, ecip);
        String send=tools.hex(output);
        out.println(send);
    }
    public byte[] recieveBinaryMsg() throws Exception
    {
        String line=new String("");
        while(true)
        {
            line=in.readLine();
            if(line==null)
                return (new String(""));
            if(!line.equals(""))
                break;
        }
        byte[] input=tools.dehex(line);
        byte[] ret=crypt(input, dcip);
        return (ret);
    }
```

natürlich muss man in seiner programm-logik darauf achten das bevor man die receiveBinaryMsg methode in eine schleife hängt die schleife der receiveMsg - methode beendet ... sonst liest diese unter umständen der binary-methode die daten-weg und das ganze geht dann irgendwie kaputt ...


----------



## kirax (11. Mrz 2011)

Alter das ist ja der reinste Graus...



> ```
> //konstruktor mit übergabe der in- und outputstreams und des AES-schlüssels
> public synccrypt(BufferedReader in, PrintStream out, SecretKey sk)
> ```


DAS ist wahrlich ein unnötiger Kommentar. Der enthält nichts was nicht schon auf den ersten Blick im Code erkennbar wäre.
Kommentare sind nicht dazu da, das was im Code steht und auf den ersten Blick(!) erkennbar ist, zu erklären, weil das tut der Code auch, sondern vielmehr zu erklären, WARUM du dich für diesen Weg entschieden hast. Und natürlich auch um schwierige Fälle zu erläutern, wenn in wenigen Codezeilen etwas gemacht wird, das nicht auf den ersten Blick erkennbar ist.

Ich geb dir dazu mal ein Beispiel:


```
public static void methode(Integer a, Integer b) {
  a = a ^ b;
  b = a ^ b;
  a = a ^ b;
}

public static void main(String[] args) {
  Integer a = 10;
  Integer b = 21;
  methode(a, b);
  methode(a, b);
  System.out.println(a);
  System.out.println(b);
}
```

Ohne Kommentare hier zu erkennen, wie die Ausgabe aussieht (und warum!), geht eigentlich nur wenn man so etwas schonmal gesehen hat oder SEEEHR fit ist. Dabei steht eindeutig im Code, was gemacht wird. Ist doch logisch.

Wenn ich deine Codefetzen schonmal gesehen hätte, wär es sicher auch kein Problem rauszulesen was passiert. Aber bei eigenem erstelltem Code ist das immer so, dass man selbst voll den Überblick hat, während der andere erstmal sich reinlesen muss.

Überleg mal wie viel Zeit du in den Code gesteckt hast. Das kannst du ein bisschen als Maß nehmen dafür, wie schwer es für jemand anders ist, den Code nachzuvollziehen. Die Zeit musst du ja nicht umsonst reinstecken. Wenn du das total easy runtergeschrieben hast (so wie ich den Fetzen oben), dann ist es natürlich auch logisch, dass andere keine große Mühe haben werden, da durchzusteigen.



> ```
> String line=new String("");
> while(true)
> {
> ...


AUA!
3 Schönheitsfehler, die übrigens nichts mit Konvention zu tun haben:

```
String line = new String("");
```
Damit nimmst du der VM die Möglichkeit eine Referenz auf einen existierenden String "" zu verwenden -> Geschwindigkeitseinbuße (innerhalb der Schleife nochmal)

```
while(true)
```
Schlimmer gehts fast nicht...
Und zu guter Letzt noch mehr als einen Austrittspunkt aus der Schleife...
All solche Dinge machen es schwer, Code nachzuvollziehen.

So jetzt bin ich erstmal genug drüber hergezogen...

Gewöhn dir echt nen anderen Stil an. Glaub mir (und den anderen hier auch) du wirst es nicht bereuen.

Übrigens: Eclipse bietet eine Tastenkombi an: SHIFT+STRG+F Damit ist alles schön eingerückt...

Edith meint übrigens:


> natürlich muss man in seiner programm-logik darauf achten das bevor man die receiveBinaryMsg methode in eine schleife hängt die schleife der receiveMsg - methode beendet ... sonst liest diese unter umständen der binary-methode die daten-weg und das ganze geht dann irgendwie kaputt ...


DAS gehört als Kommentar in den Code.


----------

