RSA Verschlüsselung

Status
Nicht offen für weitere Antworten.
M

MeinerEiner

Gast
Hallöle,
versuche mich gerade an einer RSA Verschlüsselung in Java..
Problem dabei ist, wenn ich eine Nachricht verschlüssele und sie dann entschlüssele, ist sie auf einmal doppelt vorhanden.. Sieht so aus, als ob ich die originalnachricht wohl irgendwie mit sich selbst konkateniert habe, und dann verschlüsselt.. aber ich find einfach keinen fehler.....

Zur verdeutlichung mal der quelltext :
Habe erstmal ein Schlüsselpaar erstellt..

Code:
import java.nio.*;
import java.nio.charset.*;
import java.security.*;
import java.util.Vector;

import javax.crypto.*;


public class Security {
	private KeyPair keyPair;
	private Cipher cipher;
	Charset charset;
	private final int RSABlockSize = 245;
	
	public Security(){
		String nachricht = " die nachricht zum verschlüsseln";
		ByteBuffer buffer = ByteBuffer.allocate(50);
		ByteBuffer decrypt;
		charset = Charset.forName( "ISO-8859-1" );
		buffer.put(charset.encode(nachricht));
		
		generateRSA();
		
		decrypt = encodeWithRSA(buffer,keyPair.getPublic(),RSABlockSize);
		buffer = decodeWithRSA(decrypt,keyPair.getPrivate(),RSABlockSize);
		System.out.println(charset.decode(decrypt));
		System.out.println(charset.decode(buffer));
		
	}
	
	
	
	boolean generateRSA(){
		try {
			KeyPairGenerator kpg = KeyPairGenerator.getInstance( "RSA" );
			kpg.initialize(2048);
			keyPair = kpg.genKeyPair();
			//System.out.println(keyPair.getPrivate());
			//System.out.println(keyPair.getPublic());
			return true;
		} catch (NoSuchAlgorithmException e) {return false;}
		
	}

	public static void main(String[] args) {
		Security sec = new Security();
		
	}
}


Als nächstes wird die Nachricht verschlüsselt.... Da bei RSA die blocklänge 245 byte betragen muss, wird die Nachricht auf verschiedene Bytearrays aufgeteilt in einen Vektor verpackt, und dann einzelen verschlüsselt :
Code:
//Hauptmethode zum Verschlüsseln

ByteBuffer encodeWithRSA(ByteBuffer bufferText, PublicKey pk,int blockSize){
		int allocate=0;
		byte[] byteArray = bufferText.array();
		byteArray = bufferText.array();
		Vector ByteArrays = returnByteArrays(byteArray,blockSize);
		Vector tmpArrays = new Vector();
		try {
		int temp = ByteArrays.size();
		for(int i=0; i < ByteArrays.size(); i++){
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, pk);
			byte[] tmp = cipher.doFinal((byte[])(ByteArrays.get(i)));
			allocate += tmp.length;
			tmpArrays.add(tmp);
		}
			ByteBuffer outputText = ByteBuffer.allocate(allocate);
			for(int i =0; i< tmpArrays.size();i++){
				outputText.put((byte[])(tmpArrays.get(i)));
			}
			outputText.flip();
			return outputText;
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (NoSuchPaddingException e) {
				e.printStackTrace();
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			} catch (IllegalBlockSizeException e) {
				e.printStackTrace();
			} catch (BadPaddingException e) {
				e.printStackTrace();
			}
			
			return null;

	
	}

Code:
//Methode verpackt einzelnes ByteArray in mehrere, 245 Byte grosse, ByteArrays
Vector returnByteArrays(byte[] byteArray,int size){
		Vector inputByteArrays = new Vector();
		int tp = ((int)(byteArray.length/size));
		for(int i = 0; i<=((int)(byteArray.length/size));i++){
			if(!(byteArray.length-(size*i)>245)){
				byte[] newArray = new byte[byteArray.length-(size*i)];
				for(int j=0; j < byteArray.length-(size*i);j++){
					newArray[j]=byteArray[size*i+j];
				}
			}
			else{
				byte[] newArray = new byte[size];
				for(int j=0; j < size;j++){
					newArray[j]=byteArray[size*i+j];
				}
			}
			inputByteArrays.add(byteArray);
		}
		return inputByteArrays;
	}

So.. und das scheint auch gut zu klappen..
Als verschlüsselte Nachricht erhalte ich :

Code:
ByteBuffer buffer = ByteBuffer.allocate(50);
charset = Charset.forName( "ISO-8859-1" );
ByteBuffer decrypt;
buffer.put(charset.encode(nachricht));
decrypt = encodeWithRSA(buffer,keyPair.getPublic(),RSABlockSize);
System.out.println(charset.decode(decrypt));
Ausgabe :
-ésIíÕ%ïº"E6ïmëNÓDûù`î[&¡K·³üïIUÒwÆúrÑ?þt7ÄÇÂ}m?J%sz?£ útÁ°^\ZùRyÇÂ?¶-CVGº¡>fez5!?R"·¹Kñ?q?K!µ¾µ¢&??Gæú2¯#?Ð?×û¢?hTÈqÑ·Ê8ò[?B?þßé?<£/õ?MÛ }Ú6×v?É?¾ä0jÎ?X2o6ØänU?÷ýá,ê%!º`Àp{?õ9tÀùÎ>eI%åñåü»9éf'ÞØ¥Ò£÷«½?

nun wird das ganze wirde decheffriert.. die decodiermehtode ist ähnlich der encodiermethode;
Code:
ByteBuffer decodeWithRSA(ByteBuffer bufferText, PrivateKey pk,int blockSize){
		int allocate=0;
		byte[] byteArray = bufferText.array();
		byteArray = bufferText.array();
		Vector ByteArrays = returnByteArrays(byteArray,blockSize);
		Vector tmpArrays = new Vector();
		try {
		int temp = ByteArrays.size();
		for(int i=0; i < ByteArrays.size(); i++){
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, pk);
			byte[] tmp = cipher.doFinal((byte[])(ByteArrays.get(i)));
			allocate += tmp.length;
			tmpArrays.add(tmp);
		}
			ByteBuffer outputText = ByteBuffer.allocate(allocate);
			for(int i =0; i< tmpArrays.size();i++){
				outputText.put((byte[])(tmpArrays.get(i)));
			}
			outputText.flip();
			return outputText;
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (NoSuchPaddingException e) {
				e.printStackTrace();
			} catch (InvalidKeyException e) {
				e.printStackTrace();
			} catch (IllegalBlockSizeException e) {
				e.printStackTrace();
			} catch (BadPaddingException e) {
				e.printStackTrace();
			}
			
			return null;

	
	}
Ausgabe:
Code:
buffer = decodeWithRSA(decrypt,keyPair.getPrivate(),RSABlockSize);
System.out.println(charset.decode(buffer));
und erhalte

" die nachricht zum verschlüsseln______________________________ die nachricht zum verschlüsseln __________________________________________ "

Die leerzeichen sind klar.. schliesslich war mein Bytebuffer grösser als die tatsächliche nachricht.. aber wieso erhalte ich sie auf einmal doppelt??
vielleicht kann mir ja jemand helfen?

*grüssle*
Jörg
 

ice-breaker

Top Contributor
wenn ich mich recht entsinne, war es irgendwie so, dass das N = p * q die maximale Blocklänge angibt, die 2048 Bit waren soweit ich mich erinner nur für die Primzahlen.

Ich kann mich auch gerade sehr stark irren, ist schon nen ganzen Moment her :oops:
 

0x7F800000

Top Contributor
wenn ich mich recht entsinne, war es irgendwie so, dass das N = p * q die maximale Blocklänge angibt, die 2048 Bit waren soweit ich mich erinner nur für die Primzahlen.

Also, erstmal: du hast wohl "die Anzahl der Binärstellen der Zahl N=pq gibt die Blocklänge in bits an" sagen wollen, Blöcke der Länge N passen in keinen Rechner dieser Welt, weil N monströs groß gebaut wird.

Aber selbst mit dieser Verbesserung ist die ausage noch nicht korrekt:
a^phi(N) = 1 mod N
gilt nämlich nur für Einheiten in Z/NZ, also Zahlen, die nicht 0 sind, und sich auch nicht durch p oder q teilen lassen. Also ist die Länge des Blocks wohl durch das Minimum der Anzahl der Stellen von p und q beschränkt, ansonsten könnte es schief gehen.
 

fehlerfinder

Bekanntes Mitglied
Erstmal danke für die informativen Antworten.

"die Anzahl der Binärstellen der Zahl N=pq gibt die Blocklänge in bits an"
Gut, das ist soweit verständlich.

a^phi(N) = 1 mod N
gilt nämlich nur für Einheiten in Z/NZ, also Zahlen, die nicht 0 sind, und sich auch nicht durch p oder q teilen lassen. Also ist die Länge des Blocks wohl durch das Minimum der Anzahl der Stellen von p und q beschränkt, ansonsten könnte es schief gehen.
Da ich weder Mathematiker noch Informatiker bin, wäre es klasse, wenn du das für mich nochmal etwas allgemeiner ausdrücken könntest.

Konkret:
Was ist "a", was ist "phi"?
Sind Z/NZ zwei Zahlenmengen?
Ist die Definition davon "natürliche Zahlen ungleich 0 und nicht durch p, q teilbar"?

Wenn ich dann zwei Zahlen p und q habe, z.B. zwei 78-stellige Zahlen mit einem Produkt von 155 Stellen, entspricht das also 1240Bit. Wie könnte das denn zu der im Ursprungs-Posting genannten Aussage von "maximal 254 Byte" passen?
 

0x7F800000

Top Contributor
RSA-verfahren ist im Wesentlichen dieser Satz:
Satz von Euler ? Wikipedia
der wiederum am einfachsten als Spezialfall von
Satz von Lagrange ? Wikipedia
zu verstehen ist.
Das ist bei RSA nur eben geschickt als Kryptographieverfahren umgeschrieben.
Das sind beides sehr kurze und elegante Beweise, aber als "weder- Mathematiker -noch- Informatiker" kommt man da wohl in der Notation um (das bekloppte Bildungssystem sei "dank" :mad: )

Wie das funktioniert steht also auf dem anderen Blatt geschrieben. Als Benutzer sollte man aber wissen:
Wenn man eine Zahl x verschlüsseln und dann wieder zurückgewinnen will, muss sie mit diesem N=pq teilerfremd sein. Das ist für beliebige zahlen garantiert, die zwischen 1 und min(p,q)-1 liegen. Länger sollte man den zu verschlüsselnden Block nicht machen, weil man dann die gefahr eingeht, dass am anderen Ende nichts mehr zu rekonstruieren ist.
Bei p und q 78-dezimalstellig wären das also 259~256 binärstellen, damit dürfte man imho blöcke von höchstens der Länge 256bits = 32 bytes entspricht 32 char-Zeichen verschlüsseln... Und du meinst also, dass man damit 256bytes verschlüsseln könnte? Hmm... ???:L Verstehe ich nicht :bahnhof:
 

fehlerfinder

Bekanntes Mitglied
Danke für die Links - jetzt kann ich immerhin mit dem "phi" was anfangen.

Bei p und q 78-dezimalstellig wären das also 259~256 binärstellen
aaah - jetzt habe ich endlich meinen Denkfehler gefunden: eine 155-stellige Zahl besteht natürlich mitnichten aus 155 Bytes und infolgedessen macht eine Berechnung 155 * 8Bit = 1240Bit natürlich auch überhaupt keinen Sinn...

Und du meinst also, dass man damit 256bytes verschlüsseln könnte? Hmm... ???:L Verstehe ich nicht :bahnhof:
Nein, nein, ich meinte gar nicht, sondern der Themeneröffner meinte vor knapp vier Jahren, dass RSA maximal 245Bytes auf einmal verschlüsseln kann. Und das erschien mir so spontan nicht schlüssig.

Eine mögliche Erklärung wäre die Folgende:
Ursprünglich war von einem Schlüssel mit 2048Bit die Rede, was dann ein p bzw. q mit 310 Stellen und ein N mit 618 Stellen ergibt (wenn ich mir mal die Parameter der erzeugten Keys per zB keyPair.getPrivate().toString() ausgeben lasse). Diese 618-stellige Dezimalzahl ergibt dann nach der Formel ln(N)/ln(2)/8 einen Wert von 255Bytes - somit war die ursprüngliche Angabe von 245 evtl. auch noch ein Schreibfehler.

Wie auch immer - mein Informationsbedarf ist an dieser Stelle mehr als gedeckt - VIELEN DANK!!!
 

fehlerfinder

Bekanntes Mitglied
Ich habe jetzt eine sehr pragmatische Herangehensweise gefunden, um der Begrenzung auf 245Bytes beim Verschlüsseln auf die Schliche zu kommen.

Wenn ich einen RSA-Key mit einer Länge von 2048Bit verwende und dann eine Verschlüsselung einer "langen" Nachricht (>245 Byte) vornehme, kommt sehr spontan die folgende Info:
Code:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes

Das ist eine für Nicht-Mathematiker und Nicht-Informatiker zunächst mal ausreichende Erklärung ;-)

Übrigens gilt bei Verwendung eines 1024Bit-Schlüssels eine maximale Länge von 117Bytes.

Und falls noch jemand das ursprünglich eingestellte Programm testen möchte - da hakt es an allen Ecken und Enden. Falls jemand an einer funktionstüchtigen Version interessiert ist, kann ich diese - sobald ich sie selber habe ;-) - hier einstellen. (Aber nur, wenn es entsprechendes Feedback gibt...)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M pfx-Zertifikat in Tomcat für SSL-Verschlüsselung nutzen Allgemeine Java-Themen 14
X Verschlüsselung Allgemeine Java-Themen 18
P String-Verschlüsselung - Frage zur Sicherheit Allgemeine Java-Themen 21
R Verschlüsselung falsch Allgemeine Java-Themen 3
R Verschlüsselung funktioniert nicht Allgemeine Java-Themen 5
J Passwort Verschlüsselung hash Allgemeine Java-Themen 2
D AES Verschlüsselung / Wirklich AES 128-Bit? Allgemeine Java-Themen 4
I Best Practice Verschlüsselung mit SALT Allgemeine Java-Themen 4
A Mehrfache XOR Verschlüsselung Allgemeine Java-Themen 11
Thallius Moderne sichere synchrone Verschlüsselung mit Java? Allgemeine Java-Themen 3
Ananaskirsche Verschlüsselung mit AES Allgemeine Java-Themen 4
E Verschlüsselung Allgemeine Java-Themen 4
F Schlüsselworte RSA Verschlüsselung implementieren Allgemeine Java-Themen 5
S Key (für AES-Verschlüsselung) aus String Allgemeine Java-Themen 4
M Serialisierung & Verschlüsselung Allgemeine Java-Themen 2
K Problem mit Salted - Verschlüsselung Allgemeine Java-Themen 4
Z Java E-Mail Client mit End-to-End-Verschlüsselung Allgemeine Java-Themen 4
J Verschlüsselung von Text? Allgemeine Java-Themen 2
K Vigenere- Verschlüsselung Allgemeine Java-Themen 13
M Verschlüsselung von Text und Files durch RSA (Encoding Problem) Allgemeine Java-Themen 7
T AES-Verschlüsselung mit eigenem 256 Bit Schlüssel Allgemeine Java-Themen 12
DStrohma Verschlüsselung: SALT aus Passwort generieren? Allgemeine Java-Themen 3
G AES Verschlüsselung nur bis 63 Zeichen Länge Allgemeine Java-Themen 2
M Verschlüsselung mit Cipher Allgemeine Java-Themen 5
B XOR Verschlüsselung Allgemeine Java-Themen 7
S Framework für symetrische und asymetrische Verschlüsselung Allgemeine Java-Themen 3
lumo Verschlüsselung Allgemeine Java-Themen 2
H Verschlüsselung mit Blowfish Allgemeine Java-Themen 14
C Interpreter-Fehler AES verschlüsselung mit MD5 key Allgemeine Java-Themen 6
S AES Verschlüsselung - File Headers korrupt Allgemeine Java-Themen 10
A Datei, UTF-8, NTRU-Verschlüsselung Allgemeine Java-Themen 3
B "Verschlüsselung" mit Passwort (XOR bzw. Modulo) Allgemeine Java-Themen 7
B String Verschlüsselung Allgemeine Java-Themen 6
M Verschlüsselung anwenden Allgemeine Java-Themen 6
J Verschlüsselung Allgemeine Java-Themen 22
T MD5 Verschlüsselung Nullen fehlen? Allgemeine Java-Themen 2
L [Exception] RSA Verschlüsselung. Allgemeine Java-Themen 16
C javamail signatur und verschlüsselung Allgemeine Java-Themen 2
R 128 Bit Verschlüsselung/Entschlüsselung in Java? Allgemeine Java-Themen 6
F RSA-Verschlüsselung Allgemeine Java-Themen 4
S Verschlüsselung in Java Allgemeine Java-Themen 2
G Interessant! Verschlüsselung in Java, Charset in der JVM? Allgemeine Java-Themen 14
D Eigener Key bei AES Verschlüsselung Allgemeine Java-Themen 4
T Verschlüsselung von Dateien Allgemeine Java-Themen 8
S Verschlüsselung - IllegalBlockSizeException Allgemeine Java-Themen 3
G Problem mit RSA Verschlüsselung bei .net und Java Allgemeine Java-Themen 1
D Caesar und Vigenère Verschlüsselung Allgemeine Java-Themen 2
alexpetri Verschlüsselung Allgemeine Java-Themen 13
@ [Sicherheit] Speicherung von Keys für Verschlüsselung Allgemeine Java-Themen 4
P Verschlüsselung in PHP -> Entschlüsselung in Java Allgemeine Java-Themen 2
Lazybone Caeser Verschlüsselung Allgemeine Java-Themen 6
S Verschlüsselung mit Cipher Allgemeine Java-Themen 8
S Verschlüsselung Allgemeine Java-Themen 15
J Problem mit Dateien/XOR-Verschlüsselung Allgemeine Java-Themen 5
G RSA-Verschlüsselung Allgemeine Java-Themen 1
P HMACMD5- Verschlüsselung entschlüsseln Allgemeine Java-Themen 2
I Verschlüsselung mit Pwd. - User soll Algorithmus wählen Allgemeine Java-Themen 4
J Probleme bei XOR verschlüsselung ! Allgemeine Java-Themen 5
G Verschlüsselung in Java Allgemeine Java-Themen 9
J Verschlüsselung von Daten Allgemeine Java-Themen 21

Ähnliche Java Themen

Neue Themen


Oben