Wow ... also das sich jemand den Aufwand macht und RSA selbst implementiert ist schon eine gute Leistung.
Auch bin ich persönlich von deiner Implementierung des erweiterten euklidischen Algorythmus beeindruckt.
Wobei ich dir gleich hier mal den Wind aus den Segeln deiner Begeisterung nehmen muss ...
Java stellt mit der Methode BigInteger.modInverse(BigInteger) eine sehr einfache Variante dessen bereit.
Wenn wir mal das Beispiel von Wikipedia
http://de.wikipedia.org/wiki/RSA-Kryptosystem nehmen und für e=23 und phi(N)=120 annehmen so erhalten wir mit
Java:
BigInteger d=(new BigInteger("23")).modInverse(new BigInteger("120"))
für d=47 ... was dem Beispiel auf Wikipedia entspricht.
Auch im weiteren Verlauf deines Codes sieht man das du dir die Doc zu BigInteger nicht richtig durchgelesen hast ... denn für BigInteger.multiply(BigInteger).mod(BigInteger) stellt Java auch hier wieder eine vereinfachte Methode bereit : BigInteger.modPow(BigInteger, BigInteger).
Du siehst also das man deinen Code um einiges kürzen und dadurch übersichtlicher machen kann.
Wenn das ganze allerdings als Matheübung fungieren soll bin ich von der Leistung beeindruckt und verstehe dieses für mich sehr Umständliche coding.
Dann ist weiterzusagen : RSA ist nicht für die Verschlüsselung selbst gedacht !
RSA ist kein Block-Cipher ... es ist damit also nur über Umwege möglich Informationen die Länger als die Schlüssellänge sind zu verschlüsseln.
In der Praxis wird hier ein Hybridverfahren eingesetzt : RSA+AES
Wobei RSA lediglich für den sicheren Austausch des AES Schlüssels verwendet wird *AES hat drei verschiedene Schlüssellängen : 128Bit , 192Bit , 256Bit ... der zugrundeliegende Rjindae-Algorythmus hat zu dem noch eine Variable Blocklänge von 128Bit , 192Bit , 256Bit ... von der aber in AES nur die Blocklänge von 128Bit übernommen wurde *Quelle : ebenfalls Wikipedia**
Somit passt ein AES Schlüssel also auf jeden Fall in die Schlüssellänge von RSA *bei RSA sollte mindestens eine Schlüssellänge von 1024Bit verwendet werden ... mitlerweile wurde aber diese Empfehlung aus Sicherheitsgründen auf 2048Bit angehoben*.
Das aber nur am Rande als Zusatzinformationen zum Thema RSA und Verschlüsselung damit.
Zu deinem eigentlichen Problem ...
Deine Implementierung ist soweit das du damit Zahlen verschlüsseln kannst *bei einer Länge der Primzahlen von jeweils 100Bit sollte die Schlüssellänge je nach Input zwischen 150Bit und 200Bit betragen ... womit die Mindestlänge von 256Bit für RSA noch nicht mal erreicht wird*.
Nun willst du aber auch andere Informationen als "nur Zahlen" verschlüsseln.
Um das zu erreichen musst du also erstmal diese Informationen in Zahlen umwandeln. Das geht am einfachsten mit den in Java eingebauten mitteln : String.getBytes(). Damit erhälts du ein Byte-Array. Mit diesem Byte-Array kannst du jetzt "rechnen". Ein Byte kann nur einen Wer zwischen -128 und +127 *oder 0 bis 255* haben.
Jetzt kannst du aus diesem Byte-Array einen BigInteger erzeugen : new BigInteger(byte[]) und mit diesem weiter arbeiten.
Wie du die Informationen des verschlüsselten BigInteger darstellst ist dir überlassen ... wichtig ist nur das nach dem übertragen über irgend einen Weg *meistens eine Socket-Verbindung* beim Empfänger aus deiner selbst gewählten Darstellung auch wieder genau dasselbe BigInteger-Objekt erzeugt werden kann wie es beim Absender vorhanden war. Dazu bietet sich BigInteger.toString(int) an mit dem du einen BigInteger bequem in einen Hex-String umwandeln kannst und beim Empfänger mit new BigInteger(String, int) wieder einliest *dazu setzt du für den int den Wert 16 *Hex**.
Nach dem du dann also aus dem Cipher-BigInt wieder den Plain-Text hast kannst du dir mit BigInteger.toByteArray() das Byte-Array besorgen was du beim verschlüsseln als Input verwendet hast. Daraus erzeugst du dann mit new String(byte[]) wieder einen String in dem nun dein ursprünglicher Plain-Text stehen sollte.
Hört sich alles etwas kompliziert an ... sollte aber für dich der den erweitereten euklidischen Algorythmus implementiert hat keine Schwierigkeit sein.
Ich poste dir bewusst keinen Source da ich dir nur den Denkanstoß geben wollte wie du es umsetzen könntest.
Vielleicht noch als kleines Basic am Rand : ein Rechner stellt ALLE Informationen grundsätzlich als Zahlen dar ... also kannst du grundsätzlich auch mit ALLEN Infromationen solche Rechenoperationen durchführen ... du musst nur dafür sorgen das die Informationen im richtigen Format vorliegen.
Falls du interesse an einem ausgereiften RSA-AES-Hybrid-Kryptosystem hast welches die Java-API nutzt *und dadurch wesentlich sauberer und performanter ist* kannst du dir meine Implementierung in meinm Blog zu gemüte führen.