RSA encoding

  • Antworten:19
  • Bentwortet
Julian S.
  • Forum-Beiträge: 77

12.09.2014, 22:18:04 via Website

Hallo,
Ich möchte Nachrichten verschlüsseln und muss dafür bei der Registrierung den Public Key an den Server übertragen via HTTP. Das Problem ist nun das der Key unmöglich in ein für das HTTP Protokoll angemessenes Format gebracht werden kann. Also dachte ich mir man ändert einfach den seed des KeyGen so das der Key nur zahlen und Buchstaben enthält dies scheint aber irgendwie nicht zu funktionieren. Kann mir da einer weiterhelfen?

KeyPairGenerator keyGen = null;
            try {
                keyGen = KeyPairGenerator.getInstance("RSA");

                SecureRandom secureRandom = new SecureRandom();
                byte[] chars = { 'a' ... };
                secureRandom.setSeed(chars);
                keyGen.initialize(32, secureRandom);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

            KeyPair pair = keyGen.genKeyPair();
            RSAPrivateKey privateKey = (RSAPrivateKey) pair.getPrivate();
            RSAPublicKey publicKey = (RSAPublicKey) pair.getPublic();

            String privateKeyString = new String(publicKey.getEncoded());
            String publicKeyString = new String(publicKey.getEncoded()); //Dieser String ist leider noch immer nicht in einer Url verwendbar

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

12.09.2014, 22:27:37 via Website

Fragen am Rande: Verstehe ich nicht ganz, könntest du dafür nicht ne Normale https Verbindung nehmen?
Warum muss der Public key übertragen werden, hat der Serverr kein Zertifikat, indem der Key drinne steht?

Warum ist der String in einer URL nicht verwendbar?
Befinden sich ungültige Zeichn z.b Leerzeichen und "&" dadrinne?

Gibt 2 Möglichkeiten. du urlencodest den String und schickst ihn Per get oder du lässt den String so und schickst den Per HTTP Post.

— geändert am 12.09.2014, 22:27:48

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 19:07:25 via Website

  1. Dieser public key muss in einer datanbank gespeichert werden ist also nicht dazu da eine sicherere https Verbindung aufzubauen.
  2. Klärt sich denke ich mit 1.
  3. Der sich besteht aus unzähligen Sonderzeichen die das http get protokoll nicht akzeptiert
  4. Ja

aber...

ich habe die bytes mal url save encoded mit Base64 trotzdem kam noch der fehler das die url unzulässig sei. Mit post würde es vielleicht funktionieren da ist mir aber das Risiko zu groß das bytes verloren gehen. Gibt es vielleicht eine Möglichkeit bei dem KeyPairGenerator festzulegen aus welchen Zeichen bzw bytes er bestehen darf? so könnte ich einfach festlegen das ein Key nur aus Buchstaben und Zahlen bestehen darf.

MfG,
Julian

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 19:13:45 via Website

Ich denke du solltest deine Bytes auf Buchstaben (groß/klein) und sonderzeichen beschrenken und dann ein Base64 daraus machen
Vorsicht aber: Es dürfen keine '&' vorkommen.

---
Ohne diese Einschränkung könnten nämlich uach Leerzeichen oder 0x00 Bytes generiert werden und die mag http get garnicht.
PS: Die Bytes musst du doch eh in einen String umwandeln, dass du ihn schicken kannst.
Wie sieht denn so ein beispiel aus (muss nicht komplett sein).
Bitte nicht posten, wenn es dann bei dir irgend ein Sicherheitsrisiko darstellt ;)

LG Pascal

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 19:37:00 via Website

So der code sieht wie folgt aus:

KeyPairGenerator keyGen = null;
try {
      keyGen = KeyPairGenerator.getInstance("RSA");
      SecureRandom secureRandom = new SecureRandom();
      keyGen.initialize(32, secureRandom);
} catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
}

KeyPair pair = keyGen.genKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) pair.getPrivate();
RSAPublicKey publicKey = (RSAPublicKey) pair.getPublic();

String privateKeyString = Base64.encodeToString(publicKey.getEncoded(), Base64.URL_SAFE);
String publicKeyString = Base64.encodeToString(privateKey.getEncoded(), Base64.URL_SAFE);

Und dieser error kommt wenn ich versuche eine http request zu senden:

java.lang.IllegalArgumentException: Illegal character in query at index 160: http://192.168.2.100/?page=registration&phonenumber=49555666998744123366&public_key=MEECAQAwDQYJKoZIhvcNAQEBBQAELTArAgEAAgUArEzfkQIDAQABAgQKkNZtAgMA5WcCAwDARwICcfECAj3HAgJa7Q==

Doch an der stelle 160 ist kein illegales zeichen

— geändert am 26.09.2014, 19:37:46

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 19:56:24 via Website

Da hast du allerdings recht.
Zudem hab ich gerade die Url bei mir getestet und da geht es Problemlos.
Nur was hinten rauskommt ist ein bisschen wirr:
(mit PHP [print_r($_GET);]:

Array
(
    [page] => registration
    [amp;phonenumber] => 49555666998744123366
    [amp;public_key] => MEECAQAwDQYJKoZIhvcNAQEBBQAELTArAgEAAgUArEzfkQIDAQABAgQKkNZtAgMA5WcCAwDARwICcfECAj3HAgJa7Q==
)

Ich denke dass es eher an deinen HTTP Funktionen liegt als am String.
Wo wird denn dei Exception ausgelößt?

LG Pascal

— geändert am 26.09.2014, 19:57:26

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 20:23:27 via Website

der fehler kommt bei HttpGet get = new HttpGet(url);
bei anderen http requests funktioniert es übrigens.

MfG,
Julian

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 20:34:45 via Website

Habe den gleichen Code in meiner HTTP Async Klasse.
Da tut es.
Kann es sein, dass in der url noch wirgendwelche Zeichen etc. sind, die hier auf der Webseite nicht angezeigt werden können?

LG Pascal

Edit: pass aber auf, denn über http kann man deine Abfrage abfangen und mit dem Key wer weiss was anstellen.

— geändert am 26.09.2014, 20:35:48

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 21:01:19 via Website

Tatsache im angeblich URL save kodierten string sind zwei charakter nicht in der error message angezeigt und danke für den hinweiß aber ohne den private key kann man nichts mit den public key anfangen :P Die frage ist nun wieso sind da zwei unsichtbare zeichen

— geändert am 26.09.2014, 21:01:46

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 21:02:56 via Website

Welche sind es denn?
Kannst du das irgendwie herausfinden?

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 21:21:03 via Website

Die Chars können in der console nicht angezeigt werden haben aber die bytes 10

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 21:33:29 via Website

Vielleicht doch auf Buchstaben Zahlen und Sonderzeichen beschränken

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 22:06:27 via Website

aber das ist URL_SAVE ja eigentlich :D ich habe mal gegooglet 10 byte ist wohl ein backspace

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 22:11:14 via Website

über ein Urlencode (vergleichbar mit deinem "urlsave";) sollte ein Backspace trotzdem kein problem sein.
Vlt. löschst du einfach alle \n etc .

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 22:13:51 via Website

Die sind aber meines wissens wichtig damit man es wieder in die richtigen bytes decoden kann. kennst du vieleicht noch eine andere möglichkeit einen random byte array für eine url tauglich zu machen?

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 22:20:56 via Website

Gerade sowas gefunden:

static byte[] hexFromString( String hex ) {  

    int len = hex.length();  
    byte[] buf = new byte[((len + 1) / 2)];  

    int i = 0, j = 0;  
    if ((len % 2) == 1)  
        buf[j++] = (byte) fromDigit(hex.charAt(i++));  

    while (i < len) {  

        buf[j++] = (byte) ((fromDigit(hex.charAt(i++)) << 4) |  
                            fromDigit(hex.charAt(i++)));  
    }  
    return buf;  

}

public static String asHex ( byte buf[] ) {

StringBuffer strbuf = new StringBuffer( buf.length * 2 );
int i;

for ( i = 0; i < buf.length; i++ ) {

if ( ( ( int ) buf[i] &amp; 0xff ) < 0x10 )  

   strbuf.append("0");  

strbuf.append(Long.toString((int) buf[i] &amp; 0xff, 16));  

}

return strbuf.toString();
}

Hilft das?

LG Pascal //It's not a bug, it's a feature. :) ;)

Julian S.

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 22:53:40 via Website

Perfekt hat funktioniert! Danke! :)

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

26.09.2014, 22:55:03 via Website

Kein Problem :)

Bitte setze dann deinen Thread noch auf beantwortet.

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Markus B.
  • Forum-Beiträge: 636

26.09.2014, 23:02:48 via Website

[[cite Julian S.]]
java.lang.IllegalArgumentException: Illegal character in query at index 160: http://192.168.2.100/?page=registration&phonenumber=49555666998744123366&public_key=MEECAQAwDQYJKoZIhvcNAQEBBQAELTArAgEAAgUArEzfkQIDAQABAgQKkNZtAgMA5WcCAwDARwICcfECAj3HAgJa7Q==

Doch an der stelle 160 ist kein illegales zeichen

Hi,
dein public_key attribute enthalt am Ende noch zwei Gleichzeichen. In einer URL sind zwar die folgenden Zeichen erlaubt: A-Za-z0-9-._~:/?#[]@!$&'()*+,;% allerdings sind einige für spezielle Zwecke reserviert. Hier kommen die Gleichzeichen ins Spiel, denn diese müssen escaped werden. Jag den Parameter mal durch URLEncoder.encode(...), dann sollte es passen. Dann solltest du auf die beiden Methoden von oben verzichten können.

Gruß,
Markus

— geändert am 26.09.2014, 23:05:18

Antworten
Julian S.
  • Forum-Beiträge: 77

26.09.2014, 23:54:39 via Website

Danke für die Information! Jedoch waren in dem code zwei Backspaces versteckt, welche den error verursachten.

Antworten