Verständnispoblem Cypher

Thallius

Top Contributor
Hi,

ich probiere gerade ein wenig mit dem Verschlüsseln von Daten unter Java rum. Dabei wird einem bei Google als erster der Cypher ans Herz gelegt.
Da ich eine asynchrone Verschlüsselung brauche habe ich erstmal ein keypair angelegt.

Java:
	public void generateKey() 
	{
	    try 
	    {
	    	final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
	    	keyGen.initialize(2048);
	    	final KeyPair key = keyGen.generateKeyPair();

	    	File privateKeyFile = new File(PRIVATE_KEY_FILE);
	    	File publicKeyFile = new File(PUBLIC_KEY_FILE);

	    	// Create files to store public and private key
	    	if (privateKeyFile.getParentFile() != null) 
	    	{
	    		privateKeyFile.getParentFile().mkdirs();
	    	}
	    	privateKeyFile.createNewFile();

	    	if (publicKeyFile.getParentFile() != null) 
	    	{
	    		publicKeyFile.getParentFile().mkdirs();
	    	}
	    	publicKeyFile.createNewFile();

	    	// Saving the Public key in a file
	    	ObjectOutputStream publicKeyOS = new ObjectOutputStream(new FileOutputStream(publicKeyFile));
	    	publicKeyOS.writeObject(key.getPublic());
	    	publicKeyOS.close();

	    	// Saving the Private key in a file
	    	ObjectOutputStream privateKeyOS = new ObjectOutputStream(new FileOutputStream(privateKeyFile));
	    	privateKeyOS.writeObject(key.getPrivate());
	    	privateKeyOS.close();
	    } 
	    catch (Exception e) 
	    {
			Logger.Log(e.getMessage());
	    	e.printStackTrace();
	    }
	}

So, wenn ich nun einen String verschlüssele:

Java:
	 public byte[] encrypt(String text, PublicKey key)
	 {
		 byte[] cipherText = null;
		 try 
		 {
			 // get an RSA cipher object and print the provider
			 Cipher cipher = Cipher.getInstance(ALGORITHM);
			 // encrypt the plain text using the public key
			 cipher.init(Cipher.ENCRYPT_MODE, key);
			 cipherText = cipher.doFinal(text.getBytes());
		 } 
		 catch (Exception e) 
		 {
			 Logger.Log(e.getMessage());
			 e.printStackTrace();
		 }
		 return cipherText;
	}

bekomme ich für den gleichen String jedesmal ein anderes Ergebnis. Ich kann diese Ergebnisse auch alle wunderbar Entschlüsseln aber ich frage mich wie funktioniert das?
Wenn das Ergebnis nicht deterministisch ist, dann muss ja irgendwo ein weiteres Objekt zum Verschlüsseln hinzugezogen werden. Woher aber holt er sich das?

Kann man das auch ändern, so das das Ergebnis deterministisch ist. Das bräuchte ich nämlich um die Daten weiter verarbeiten zu können.

Gruß

Claus
 
Zuletzt bearbeitet:

Tobse

Top Contributor
Sorry wenn ich da so direkt bin: wenn Du das mit dem Verschlüsseln ernst meinst, solltest Du dir die Mechaniken bewusst machen, bevor du Code schreibst. An sonsten hast du ~99% Chance, dass dein Code nachher unsicher (und damit alle Verschhlüsselung, die er gemacht hat, hinfällig) ist.

Um deine Frage zu beantworten: Das passiert wegen des Paddings (im Falle von RSA PKCS#7). Wenn du das gleiche Experiment mal mit AES in Java machst, wirst du dieses "Phänomen" (ist eigentlich keins) nicht beobachten können. Das liegt daran, dass das bei AES in Java verwendete PKCS#5 Padding in der Tat deterministisch (und deswegen inzwischen auch veraltet) ist.

Lektüre:
Padding (Informatik) (mit deutlich mehr Info aber Englisch: Padding (cryptography) - Wikipedia, the free encyclopedia)
Und auchnoch unbedingt wichtig für sichere Verschlüsselung: Block cipher mode of operation - Wikipedia, the free encyclopedia
 
Zuletzt bearbeitet:

Thallius

Top Contributor
Hallo Tobse,

Ich bin ja gerade dabei mich in die Sachen einzulesen. Deswegen ja auch meine Fragen und ich bin froh über jede info die ich bekomme ohne mich durch die original Dokus durchwühlen zu müssen.

Du meinst also, es macht keinen Sinn auf das Padding zu verzichten weil ich dann ein zu großes Sicherheitsloch habe? Ich könnte alternativ auch einen sha512() oder einen hmac() Hash von den unverschlossenen Daten machen und diese zur Identifizierung benutzten. Das wäre zwar etwas mehr Datenverlusten, dafür bin ich aber wieder was die Sicherheit angeht auf dem neusten Stand.

Gruß

Claus
 

Tobse

Top Contributor
Auf Padding zu verzichten macht deshalb keinen Sinn, weil du dann nurnoch Klartexte verschlüsseln kannst, welche ein vielfaches der Cipher-Blockgröße lang sind. Ausserdem tragen die Zufallswerte im Padding (welche die Daten an sich nicht beeinflussen aber das Ergebnis der Verschlüsselung 100%ig verändern) zur Sicherheit bei. Wenn du den gleichen Klartext zweimal verschlüsselst kann ein Aussenstehender nicht erkennen, dass es der selbe war.
 
Zuletzt bearbeitet:

Oben