SSL Socketverbindung mit Java

L

Leo2007

Hallo,

für ein Projekt benötige ich eine SSL - Socket Verbindung zwischen zwei PCs (einer Server der andere Client). Eine "normale" Socket Verbindung ist kein Problem, das hab ich schon hinbekommen.
Allerdings benötige ich eine SSL - Verbindung. Ich hab schon mehreren Bücher gewälzt und auch das Internet durchsucht, aber eine verständliche Erklärung, wie ich eine SSL-Verbindung und was ich dafür alles benötige, hab ich noch nicht gefundenn.
Leider auch keine funktionierendes Beispielprogramm.

Es wäre toll, wenn mir jemand weiterhelfen kann! Dafür bedanke ich mich schon mal herzlich.

Leo2007
 
Hallo,

um eine SSL Socket Verbindung unter Java richtig hinzubekommen muss man ein wenig mehr Aufwand in die Konfiguration stecken, als man es von der normalen Socketprogrammierung gewohnt ist. Insbesondere muss man den lokalen KeyStore bzw. den Truststore auf beiden Seiten (Server/Client) entsprechend konfigurieren dass die passenden Zertifikate vorliegen. Wie das geht findet sich beispielsweise hier:
http://java.sun.com/javase/6/docs/technotes/tools/index.html#security
http://java.sun.com/javase/6/docs/technotes/tools/windows/keytool.html
http://java.sun.com/javase/6/docs/api/javax/net/ssl/package-summary.html
http://java.sun.com/j2ee/1.4/docs/tutorial/doc/Security6.html
http://java.sun.com/javase/6/docs/technotes/guides/security/index.html
...

Hier mal ein kleines (lokales Beispiel)
Konfiguration unseres KeyStores / Truststores (ist in unserem Beispiel gleich)
Code:
keytool -genkey -keystore SSLKeyStore -alias SSLCertificateWithRSA -keyalg RSA

C:\Dokumente und Einstellungen\Tom>keytool -genkey -keystore SSLKeyStore -alias SSLCertificateWithRSA -keyalg RSA
Geben Sie das Keystore-Passwort ein:
Wie lautet Ihr Vor- und Nachname?
 [Unknown]:  Thomas Darimont
Wie lautet der Name Ihrer organisatorischen Einheit?
 [Unknown]:  BOB
Wie lautet der Name Ihrer Organisation?
 [Unknown]:  NoName Inc.
Wie lautet der Name Ihrer Stadt oder Gemeinde?
 [Unknown]:  Sametown
Wie lautet der Name Ihres Bundeslandes oder Ihrer Provinz?
 [Unknown]:  United Kingdom Ballern
Wie lautet der Landescode (zwei Buchstaben) f³r diese Einheit?
 [Unknown]:  BA
Ist CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=United Kingdom Ballern, C=BA richtig?
 [Nein]:  ja

Geben Sie das Passwort f³r <SSLCertificateWithRSA> ein.
        (EINGABETASTE, wenn Passwort dasselbe wie f³r Keystore):
Hier unser Beispiel:
Java:
/**
 * 
 */
package de.tutorials;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

/**
 * @author Tom
 * 
 */
public class SSLSocketExample {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Executors.newSingleThreadExecutor().execute(new Server());
        Executors.newSingleThreadExecutor().execute(new Client());
    }

    static class Server implements Runnable {
        public void run() {
            try {
                SSLServerSocket serverSocket = (SSLServerSocket) SSLServerSocketFactory
                        .getDefault().createServerSocket(5678);
                System.out.println("Server ready..." + serverSocket);

                System.out
                        .println("Supported Cipher Suites: "
                                + Arrays
                                        .toString(((SSLServerSocketFactory) SSLServerSocketFactory
                                                .getDefault())
                                                .getSupportedCipherSuites()));

                SSLSocket socket = (SSLSocket) serverSocket.accept();
                SSLSession sslSession = socket.getSession();
                String cipherSuite = sslSession.getCipherSuite();
                System.out.println(cipherSuite);

                Scanner scanner = new Scanner(socket.getInputStream());
                System.out.println("Reading...");
                while (scanner.hasNextLine()) {
                    System.out.println("Server received: " + scanner.nextLine());
                }
                scanner.close();

                socket.close();

                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static class Client implements Runnable {
        public void run() {
            try {

                SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault()
                        .createSocket("localhost", 5678);
                PrintWriter printWriter = new PrintWriter(socket
                        .getOutputStream());
                System.out.println("Client -> sending...");
                for (int i = 0; i < 100; i++) {
                    String message = "Hallo: " + i;
                    System.out.println("Client sent: " + message);
                    printWriter.println(message);
                    printWriter.flush();
                    TimeUnit.SECONDS.sleep(1);
                }
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Welches wir mit folgenden JVM-Argumenten starten:
Code:
-Djavax.net.debug=all -Djavax.net.ssl.keyStore="C:\Dokumente und Einstellungen\Tom\SSLKeyStore"  -Djavax.net.ssl.keyStorePassword=DAS_KEYSTORE_PASSWORD -Djavax.net.ssl.trustStore="C:\Dokumente und Einstellungen\Tom\SSLKeyStore" -Djavax.net.ssl.trustStorePassword=DAS_KEYSTORE_PASSWORD
Hat alles geklappt erhalten wir im Beispiel folgende Ausgabe:
Code:
keyStore is : C:\Dokumente und Einstellungen\Tom\SSLKeyStore
keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
***
found key for : sslcertificatewithrsa
chain [0] = [
[
  Version: V3
  Subject: CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=United Kingdom Ballern, C=BA
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 1024 bits
  modulus: 96761635240280693883754066205346408515216599797792986817515492560834238534684244533010747990087839321942530784271842944878803220169005063223322111578523574873352707907346382626497392508251961263818571937886540769911292676168016765381521084780248843055493776347023914911829526853981670969774696669666197101027
  public exponent: 65537
  Validity: [From: Wed Mar 07 22:51:47 CET 2007,
               To: Tue Jun 05 23:51:47 CEST 2007]
  Issuer: CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=United Kingdom Ballern, C=BA
  SerialNumber: [    45ef33f3]

]
  Algorithm: [SHA1withRSA]
  Signature:
0000: 3B 5B E6 1A 5F 8D 1D 15   E4 6F 3D 53 3B 3D 7F 29  ;[.._....o=S;=.)
0010: 23 03 63 CE 01 23 F5 17   D3 A6 32 00 EF C6 A2 2B  #.c..#....2....+
0020: 43 16 61 C4 2C 9F 07 48   6A 70 AD A0 5E 81 C4 7B  C.a.,..Hjp..^...
0030: 2C 39 DE 19 DF 50 4A DA   DB 56 5E 7A EB 74 5F 6F  ,9...PJ..V^z.t_o
0040: 38 F3 CF 11 FB 35 C1 3B   06 38 95 04 5C 07 CF AB  8....5.;.8..\...
0050: 38 B1 4D 1D 6B 95 97 B4   5F 24 97 61 CE 48 EE 4C  8.M.k..._$.a.H.L
0060: BF 94 83 5D D5 20 EC D7   DF EE A5 E2 A0 13 0A 98  ...]. ..........
0070: D5 45 74 A4 84 DD 85 53   04 1C 24 10 D6 50 7D 34  .Et....S..$..P.4

]
***
***
found key for : tomssslcertificate
chain [0] = [
[
  Version: V3
  Subject: CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=UNITED KINGDOM Ballern, C=BA
  Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3

  Key:  Sun DSA Public Key
    Parameters:DSA
    p:     fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400 c31e3f80 b6512669
    455d4022 51fb593d 8d58fabf c5f5ba30 f6cb9b55 6cd7813b 801d346f f26660b7
    6b9950a5 a49f9fe8 047b1022 c24fbba9 d7feb7c6 1bf83b57 e7c6a8a6 150f04fb
    83f6d3c5 1ec30235 54135a16 9132f675 f3ae2b61 d72aeff2 2203199d d14801c7
    q:     9760508f 15230bcc b292b982 a2eb840b f0581cf5
    g:     f7e1a085 d69b3dde cbbcab5c 36b857b9 7994afbb fa3aea82 f9574c0b 3d078267
    5159578e bad4594f e6710710 8180b449 167123e8 4c281613 b7cf0932 8cc8a6e1
    3c167a8b 547c8d28 e0a3ae1e 2bb3a675 916ea37f 0bfa2135 62f1fb62 7a01243b
    cca4f1be a8519089 a883dfe1 5ae59f06 928b665e 807b5525 64014c3b fecf492a

  y:
    b6365a4f 4ccc3764 9da2b0e4 69413f58 34671282 57c4c9a2 7024e3bb 86f7533a
    2414a1bb b221d886 17b17fd8 2298727f 7c427591 ad19a98f 7794d505 45002c8e
    b6f84e02 ce370940 768680f2 b601c6de 5e718cf6 a0816e07 45c58dc2 755ce99f
    f05dd83c 8e7f7ed7 ed795516 d92afa87 cb117a0f 164af062 23718f0c eda8d95b

  Validity: [From: Wed Mar 07 22:47:13 CET 2007,
               To: Tue Jun 05 23:47:13 CEST 2007]
  Issuer: CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=UNITED KINGDOM Ballern, C=BA
  SerialNumber: [    45ef32e1]

]
  Algorithm: [SHA1withDSA]
  Signature:
0000: 30 2C 02 14 72 58 43 77   A1 C4 67 0D 6C E2 8A 4F  0,..rXCw..g.l..O
0010: 63 78 FD F5 58 16 06 E9   02 14 77 2E 94 CE 50 39  cx..X.....w...P9
0020: 2A 99 75 8A D1 F5 D7 97   2F 42 F3 B1 3A 7E        *.u...../B..:.

]
***
trustStore is: C:\Dokumente und Einstellungen\Tom\SSLKeyStore
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
  Subject: CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=United Kingdom Ballern, C=BA
  Issuer:  CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=United Kingdom Ballern, C=BA
  Algorithm: RSA; Serial number: 0x45ef33f3
  Valid from Wed Mar 07 22:51:47 CET 2007 until Tue Jun 05 23:51:47 CEST 2007

adding as trusted cert:
  Subject: CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=UNITED KINGDOM Ballern, C=BA
  Issuer:  CN=Thomas Darimont, OU=BOB, O=NoName Inc., L=Sametown, ST=UNITED KINGDOM Ballern, C=BA
  Algorithm: DSA; Serial number: 0x45ef32e1
  Valid from Wed Mar 07 22:47:13 CET 2007 until Tue Jun 05 23:47:13 CEST 2007

trigger seeding of SecureRandom
done seeding SecureRandom
Server ready...[SSL: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=5678]]
Supported Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_RSA_WITH_NULL_MD5, SSL_RSA_WITH_NULL_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_DH_anon_WITH_AES_128_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_RC4_128_SHA, TLS_KRB5_WITH_RC4_128_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
matching alias: sslcertificatewithrsa
Client -> sending...
Client sent: Hallo: 0
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1156528271 bytes = { 123, 6, 165, 35, 40, 20, 158, 178, 47, 105, 105, 19, 21, 171, 249, 238, 218, 122, 153, 57, 160, 106, 130, 41, 53, 242, 249, 112 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA]
Compression Methods:  { 0 }
***
[write] MD5 and SHA1 hashes:  len = 73
0000: 01 00 00 45 03 01 45 EF   39 8F 7B 06 A5 23 28 14  ...E..E.9....#(.
0010: 9E B2 2F 69 69 13 15 AB   F9 EE DA 7A 99 39 A0 6A  ../ii......z.9.j
0020: 82 29 35 F2 F9 70 00 00   1E 00 04 00 05 00 2F 00  .)5..p......../.
0030: 33 00 32 00 0A 00 16 00   13 00 09 00 15 00 12 00  3.2.............
0040: 03 00 08 00 14 00 11 01   00                       .........
pool-2-thread-1, WRITE: TLSv1 Handshake, length = 73
[write] MD5 and SHA1 hashes:  len = 98
0000: 01 03 01 00 39 00 00 00   20 00 00 04 01 00 80 00  ....9... .......
0010: 00 05 00 00 2F 00 00 33   00 00 32 00 00 0A 07 00  ..../..3..2.....
0020: C0 00 00 16 00 00 13 00   00 09 06 00 40 00 00 15  ............@...
0030: 00 00 12 00 00 03 02 00   80 00 00 08 00 00 14 00  ................
0040: 00 11 45 EF 39 8F 7B 06   A5 23 28 14 9E B2 2F 69  ..E.9....#(.../i
0050: 69 13 15 AB F9 EE DA 7A   99 39 A0 6A 82 29 35 F2  i......z.9.j.)5.
0060: F9 70                                              .p

### schnipp ###
Client sent: Hallo: 5
Padded plaintext before ENCRYPTION:  len = 26
0000: 48 61 6C 6C 6F 3A 20 35   0D 0A E5 67 DA C6 F9 09  Hallo: 5...g....
0010: BE 93 73 B3 BE 68 1E BF   AC 5F                    ..s..h..._
pool-2-thread-1, WRITE: TLSv1 Application Data, length = 26
[Raw write]: length = 31
0000: 17 03[Raw read]: length = 5
0000: 17 03 01 00 1A                                  01     00 1A 4B 57 BD   EE 75 18 E2. 26. FF 23...
[Raw read]: length = 26
 F2  .....KW..u..&.#.
0010: 92 9A FE 79 A5 FB 2A 290   980 08 F080 84: 4 6EB BA 57 82     . BD..y..*)....n..
 EE 75 18 E2 26   FF 23 F2 92 9A FE 79 A5  KW..u..&.#....y.
0010: FB 2A 29 98 08 F8 84 6E   BA 82                    .*)....n..
pool-1-thread-1, READ: TLSv1 Application Data, length = 26
Padded plaintext after DECRYPTION:  len = 26
0000: 48 61 6C 6C 6F 3A 20 35   0D 0A E5 67 DA C6 F9 09  Hallo: 5...g....
0010: BE 93 73 B3 BE 68 1E BF   AC 5F                    ..s..h..._
Server received: Hallo: 5
...
Gruß Tom
 
gibt es dazu auch ein Beispiel wie man über ssl Socket's Methoden aufruft, z.B. über RMI
dafür kann man ja nicht einfach per socket.getInputStream() zugreifen sondern muß die Methoden aufrufen...
Nur wie registriert man einen Server über einen SSL Socket?
 
Ich grab mal einen alten Thread aus weil meine Frage hier gut passt.


Gibt es eine Möglichkeit eine SSL-Socketverbindung zu erstellen ohne das keystore-File beim Programmaufruf mitgeben zu müssen?

Ich habe eine JavaWebStart-Anwendung. D.h der User ruft das Programm einfach auf.

Kann ich das keystore-File in das Jar packen und im Code es laden?


Oder gibt es eine einachere Möglichkeit eine sichere Socket-Verbindung zu erstellen?
 
Die Frage ist zwar mittlerweile schon ziemlich alt aber vielleicht hilft es ja noch jemanden.
Man kann die Argumente auch im Code setzen, mit:
Java:
        System.setProperty("javax.net.ssl.keyStore", keyPath);
        System.setProperty("javax.net.ssl.keyStorePassword", password);
        System.setProperty("javax.net.ssl.trustStorePassword", password);
        System.setProperty("javax.net.ssl.trustStore", keyPath);

Und den keystore-File kann man auch in die Jar mitreinpacken.
 
Zurück