Avatar billede trp79 Nybegynder
22. juli 2003 - 14:43 Der er 44 kommentarer og
1 løsning

kryptering/dekryptering + socket.

Jeg har en klient som skal valideres (eller hedder det verificeres?) af en server før klienten kan få adgang til en db på serveren.

Det er stand-alone apps jeg har lavet og kunne godt tænke mig at kryptere det login-password, der sendes fra klient til server, således at det ikke lige sådan bliver opsnappet. Når klienten er valideret af serveren uploades nogle objekter til serveren - disse bør vel også krypteres eller?

Er det sikkert at bruge DES som kryptering eller skal der andre midler til? Det kommer selvfølgelig an på forholdene, men er det meget let at bryde en DES kryptering?

Jeg fandt denne klasse et andet sted på exp:
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Des {
    private Cipher des;
    private SecretKey deskey;
    public Des(String key) {
        try {
            Security.addProvider(new com.sun.crypto.provider.SunJCE());
            des = Cipher.getInstance("DES/ECB/PKCS5Padding");
            deskey = new SecretKeySpec(key.getBytes(), "DES");
        } catch(Exception e) {
        }
    }
    public byte[] encrypt(byte[] plaindata) throws Exception {
        des.init(Cipher.ENCRYPT_MODE, deskey);
        return des.doFinal(plaindata);
    }
    public byte[] decrypt(byte[] cipherdata) throws Exception {
        des.init(Cipher.DECRYPT_MODE, deskey);
        return des.doFinal(cipherdata);
    }
    public static void main(String[] args) throws Exception {
        Des ec = new Des("hemmelig");
        String s1 = "Dette er en test";
        byte[] b1 = ec.encrypt(s1.getBytes());
        byte[] b2 = ec.decrypt(b1);
        String s2 = new String(b2);
        System.out.println(s2);
    }
}

vil den være passende at bruge for mit vedkommende og er det iøvrigt muligt at gøre brug af denne krypteringsform i midlets (DES krypt/dekrypt er vel forholdsvis tung)?

Hvis det er fint med DES hvordan sender og modtager jeg så et array over socket?

Håber ikke du har tabt modet pga. de mange spørgsmål!
Mvh
Torben
Avatar billede arne_v Ekspert
22. juli 2003 - 14:59 #1
DES er ikke længere sikkert.

3DES eller AES burde være sikkert stadigvæk.

DES er formentlig også godt nok til dig medmindre NSA er ude efter dig.

Til socket kommunikation er det ofte en fordel at bruge ObjectOutputStream
og ObjectInputStream fordi så kan man bare sende objekter frem og tilbage.
Avatar billede arne_v Ekspert
22. juli 2003 - 14:59 #2
Hvis du vil kryptere hele socket traffikken, så kan du jo overveje
at bruge SSL sockets.
Avatar billede arne_v Ekspert
22. juli 2003 - 15:02 #3
To yderligere betragtninger:

1)  Der er stor forskel på at kryptere på transport niveau som med SSL
    og kryptere på applikations niveau som med krypteret password.

2)  Det er strengt taget ikke sikkert at sende passwordet krypteret.
    Fordi hvis nogen opsnapper beskeden, så kan de jo bare sende
    det samme krypterede password uden at kende hverken plain password
    eller key. Hvis krypteret password skal være sikkert så skal
    det krypterede passwor kun kunen bruges en gang.
Avatar billede arne_v Ekspert
22. juli 2003 - 15:07 #4
AES eksempel:

import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AES {
    private Cipher aes;
    private SecretKey aeskey;
    public AES(String key) {
        try {
            Security.addProvider(new com.sun.crypto.provider.SunJCE());
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            aes = Cipher.getInstance("AES");
            aeskey = new SecretKeySpec(key.getBytes(), "AES");
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    private byte[] encrypt(byte[] plaindata) throws Exception {
        aes.init(Cipher.ENCRYPT_MODE, aeskey);
        return aes.doFinal(plaindata);
    }
    private byte[] decrypt(byte[] cipherdata) throws Exception {
        aes.init(Cipher.DECRYPT_MODE, aeskey);
        return aes.doFinal(cipherdata);
    }
    public static void main(String[] args) throws Exception {
        AES ec = new AES("hemmelighemmelig");
        String s1 = "Dette er en test";
        byte[] b1 = ec.encrypt(s1.getBytes());
        byte[] b2 = ec.decrypt(b1);
        String s2 = new String(b2);
        System.out.println(s2);
    }
}

<1.4.2: download bouncycastle JCE provider og put i classpath
1.4.2+: slet den linie der refererer til bouncycastle
Avatar billede trp79 Nybegynder
22. juli 2003 - 17:19 #5
Nu virker søgningen desværre ikke pt her på exp. Kan man "uden videre" arbeje med en ssl protokol? Det kræver vel et certifikat, som man endten selv udsteder eller får en anden til?
Jeg bruger i forvejen ObjectOutputStream og ObjectInputStream til at sende og modtage mine objekter med. Problemet ligger i at disse objekter indeholder fortrolige oplysninger, det er selvfølgelig ikke sådan FBI fortrolige men diverse informationer omkring diverse firmaer som nogle person har indsamlet. Det er vel ikke nok så at holde passwordene til serverprocessen krypteret...
Avatar billede arne_v Ekspert
22. juli 2003 - 17:33 #6
SSLSocket er med i J2SE 1.4 !

Du kan altid lave dit eget certfikat.

Så garanterer Verisign eller en anden ikek at du er den su siger du er, men
krypteringen er lige god.
Avatar billede trp79 Nybegynder
22. juli 2003 - 17:41 #7
Du kender ikke et godt link til en torturial eller lignende, der viser hvordan man laver sit eget certifikat og hvordan man bruger ssl i j2se .14?
Avatar billede arne_v Ekspert
22. juli 2003 - 17:49 #8
Hent 1.4 docs og læs:

JavaTM Secure Socket Extension (JSSE) Reference Guide

jeg tror faktisk at den forklarer det meste.
Avatar billede snakebyte Nybegynder
23. juli 2003 - 11:16 #9
Ellers kan bogen Java Cryptography nok hjælpe.
Den er godt nok et par år gammel efterhånden, men den forklarer fint hvordan man bruger kryptering i Java
Avatar billede trp79 Nybegynder
23. juli 2003 - 18:00 #10
Jeg har nu fået ændret i koden, således at den bruger ssl.
Mit problem er nu er lave et certifikat, jeg er ikke helt med på hvordan det skal gøres :o( Har du nogen erfaringer med det? Jeg har kigget på:
http://java.sun.com/j2se/1.4.1/docs/guide/security/jsse/JSSERefGuide.html#SecureConnSample
Avatar billede arne_v Ekspert
23. juli 2003 - 19:41 #12
Jeg har lavet et certifikat til at teste Tomcat med https (som også er SSL).
Avatar billede arne_v Ekspert
23. juli 2003 - 19:42 #13
Da fulgte jeg bare vejledningen:
  http://jakarta.apache.org/tomcat/tomcat-4.1-doc/ssl-howto.html
og det virkede i første hug.
Avatar billede arne_v Ekspert
23. juli 2003 - 19:43 #14
Men den JSSE vejledning burde vel også være til at følge.
Avatar billede trp79 Nybegynder
23. juli 2003 - 21:18 #15
Okey, så har jeg nok taget helt fejl... Jeg troede faktisk at det var muligt at knytte et certifikat til en java-server proces, uden at have fx en tomcat server kørende, men det er åbenbart umuligt eller?
Avatar billede trp79 Nybegynder
23. juli 2003 - 21:20 #16
jeg har jo bare en java klient og en java server, hvor jeg gerne vil have kommunikationen til at foregå gennem SSL. Det er ikke en web-applikation.
Avatar billede arne_v Ekspert
23. juli 2003 - 21:21 #17
Øh - selvfølgelig er det muligt.

SSL er helt uafhængigt af om det er Tomcat eller en egen server applikation.

Men det betyder også at det er samme måde man ligger certifikat ind på !
Avatar billede trp79 Nybegynder
23. juli 2003 - 21:25 #18
Okey det lyder godt! Så kan jeg jo roligt løbe vejledningen igennem :o)
Avatar billede arne_v Ekspert
23. juli 2003 - 21:30 #19
Jeg tror ikke at den giver så meget.

J2SE dokumentation bruger brugernavn duke.

Tomcat bruger brugernavn tomcat.

Og det er vist forskellen.
Avatar billede arne_v Ekspert
23. juli 2003 - 21:35 #20
Men det fortæller hvordan man laver keystore.

Og SSLSocketClientWithClientAuth eksemplet viser hvordan man bruger det
i sin applikation.
Avatar billede arne_v Ekspert
23. juli 2003 - 21:35 #21
Og hvis du synes at SSL er svært i Java, så skulle du se det i C !!!!
Avatar billede trp79 Nybegynder
23. juli 2003 - 22:44 #22
Okey nu har jeg så fået lavet certifikatet og ifølge sun's vejledning gør man så:

To make the samplecacerts file available to both the client and the server, you can either copy it to the file <java-home>/lib/security/jssecacerts, rename it cacerts and use it to replace the <java-home>/lib/security/cacerts file, or add the following option to the command line when running the java command for both the client and the server:

-Djavax.net.ssl.trustStore=path_to_samplecacerts_file

Men jeg kan desværre ikke få nogle af delene til at virke :o(

I mit "javahome", som er C:\j2sdk1.4.1_01 har jeg ikke et underbibliotek til lib som hedder security. Dette bibliotek har jeg derimod i mit J2EE home-dir.
Måske der bliver rodet lidt rundt pga classpath eller lign.?
Min certifikat fil bliver fint oprettet og eksekverer jeg certifikat filen, kan jeg også uden problemer installere certifikatet.

Hvis jeg skriver java Server -Djavax.net.ssl.trustStore=c:\cacerts
får jeg fejlen:
fejl i server.java...: javax.net.ssl.SSLException: No available certificate corresponds to the SSL cipher suites which are enabled.

Har du nogle ideer til hvad jeg kan gøre?
Avatar billede arne_v Ekspert
24. juli 2003 - 07:33 #23
Hm.

Jeg bliver nok nødt til at lave et complet eksempel så ...
Avatar billede trp79 Nybegynder
24. juli 2003 - 08:43 #24
Det burde jo virke... Jeg fandt dette inde på vejledningssiden:

Exception, "No available certificate corresponding to the SSL cipher suites which are enabled"
Problem: When I try to run a simple SSL Server program, the following exception is thrown:

Exception in thread "main" javax.net.ssl.SSLException:
No available certificate corresponding to the SSL
cipher suites which are enabled...

Cause: Various cipher suites require certain types of key material. For example, if an RSA cipher suite is enabled, an RSA keyEntry must be available in the keystore. If no such key is available, this cipher suite cannot be used. If there are no available key entries for all of the cipher suites enabled, this exception is thrown.

Solution: Create key entries for the various cipher suite types, or use an anonymous suite. (Be aware that anonymous ciphersuites are inherently dangerous because they are vulnerable to "man-in-the-middle" attacks, see RFC 2246.) Refer to the following sections to learn how to pass the correct keystore and certificates:

Relationship Between Classes
Customizing the Default Key and Trust Stores, Store Types, and Store Passwords
Additional Keystore Formats

(de sidste 3 linier er links)

Jeg forstår bare ikke lige hvad det er solutionen er :o(
Avatar billede arne_v Ekspert
24. juli 2003 - 08:50 #25
Jeg læser det som at:

SSLContext.getInstance("TLS")
KeyManagerFactory.getInstance("SunX509")

skal matche hvad der er i key storen.

X509 er en certifikak type.

TLS er bare versionen af SSL.
Avatar billede trp79 Nybegynder
24. juli 2003 - 09:50 #26
Jeg føler mig "lidt" lost nu, som jeg læser det hos sun, så er TLS og SSL to forskellige protokoller (jvf. http://java.sun.com/j2se/1.4.1/docs/guide/security/jsse/JSSERefGuide.html#Introduction )

Og ønsker man blot at benytte SSL kan man gøre det som i eksemplet (http://java.sun.com/j2se/1.4.1/docs/guide/security/jsse/JSSERefGuide.html#UnsecureSecure). Dette har jeg implementeret i min kode:

import java.net.*;
import java.io.*;
import java.lang.*;
import java.util.*;
import javax.net.ssl.*;

public class Server
{
    Socket users[] = new Socket[50];
    int i = 0;
    static Socket incoming;

    public Server()
    {

    }

    public void forbindelse(Server s)
    {
        //Initializere netværks forbindelse
        SSLServerSocket serverSocket;
        try
        {

            SSLServerSocketFactory sslSrvFact =
                (SSLServerSocketFactory)
                SSLServerSocketFactory.getDefault();
            serverSocket = (SSLServerSocket)sslSrvFact.createServerSocket(8205);

            //Start uendelig løkke indtil information kommer
            while(true)
            {
                //acepter besked
                SSLSocket incoming= (SSLSocket)serverSocket.accept();

                users[i] = incoming;
                i++;

                thread(incoming, s);
            }
        }
        catch(Exception exc){System.out.println("fejl i server.java...: "+ exc.toString());}
    }

    public void thread(SSLSocket incoming, Server s)
    {
        //opret ny tråd
        dataThread ct= new dataThread(incoming, s);
        ct.start();
    }

    public static void main(String args[])
    {
        Server s = new Server();

        s.forbindelse(s);
    }
}

Jeg har altså brugt SSLServerSocketFactory.getDefault(); Ønsker man at bruge TLS har jeg forstået det somom man kan gøre som i eks. http://java.sun.com/j2se/1.4.1/docs/guide/security/jsse/JSSERefGuide.html#RunningCFS

Er jeg helt galt gal på den?
Avatar billede arne_v Ekspert
24. juli 2003 - 09:58 #27
Nu er jeg ikke ekspert ud i SSL.

Men så vidt jeg ved er TLS et nyt navn for hvad der ellers skulle have
heddet SSL V4. D.v.s. at det er SSL V2 -> SSL V3 -> TLS.
Avatar billede trp79 Nybegynder
24. juli 2003 - 14:59 #28
Det virker nu næsten efter hensigten :o) :o)
Jeg kan godt benytte mig af DataInputStream og PrintStream, men når jeg arbejder med objektOutputStream går det ikke så godt :o(

Jeg får en nullpointer exception på denne linie:
output = new ObjectOutputStream (socket.getOutputStream());
output erklæres ved: private ObjectOutputStream output;

Har du nogen ide om man skal gøre noget specielt i forbindelse med objectInputStrem og objektOutputStream? Det funkede nemlig glimrende før jeg lavede det om til TLS
Avatar billede arne_v Ekspert
24. juli 2003 - 15:09 #29
Umiddelbart syntes jeg at det skulle være transparent for Object*Stream
hvorvidt det er en Socket eller en SSLSocket.
Avatar billede trp79 Nybegynder
24. juli 2003 - 16:48 #30
Jeg kan simpelthen ikke finde ud af hvorfor det ikke rigtig spiller når kommunikationen foregår over SSLSocket. Jeg har søgt på google, men jeg kan ikke finde et svar.

Jeg har lagt et billed på på www.confunded.dk/TP/fejl.JPG hvor man kan se fejlen. Og den linie den opstår i :o( Den prompt der er øverst er server prompten og den der er nederst er klienten.
Jeg kører localhost.
Avatar billede jpvj Nybegynder
24. juli 2003 - 16:56 #31
SSL er en gammel NetScape standard. SSL3 er den nyeste, og blev sendt i RFC draft i 1996. Den blev aldrig Standard Track (hvilket i praksis betyder at den ikke bør bruges eller refereres til), men den er alligevel - pga. NS dominans i 90'erne - blevet de facto standard.

IETF dannede i 1996 TLS working group. Se http://www.ietf.org/html.charters/tls-charter.html

TLS 1.0 ligger meget tæt på SSL v.3 (præcis samme opbygning, handshakes osv). og har været RFC Internet Standard Track siden 1999. TLS er en forkortelse for Transport Layer Security og det er målet at TLS bliver den fælles standard.

Mvh JP
- der sidder og sveder med sit eksamensprojekt!
Avatar billede trp79 Nybegynder
24. juli 2003 - 17:09 #32
--> jpvj
Du har ikke en ide til et svar på min kommentar: 24/07-2003 14:59:28 ?
Jeg bruger TLS.
Avatar billede jpvj Nybegynder
24. juli 2003 - 17:11 #33
trp79> Beklager. Jeg er ikke java kyndig nok. Skal selv lave noget SSL/TLS socket programmering i Java løbet af de næste par dage, så måske støder jeg på noget. Jeg vil dog være meget optaget de næste 14 dage, så jeg kommer måske ikke forbi...

arne_v plejer ellers at være ganske stabil :-)

JP
Avatar billede arne_v Ekspert
24. juli 2003 - 17:52 #34
Den linie bør kun kunne give null pointer exception, hvis socket er null.

Så kan du ikke lige prøve at teste på det.

Hvis socket faktisk er null, så må vi prøve at trace hvorfor den er det med
SSLSocket og ikke med normale sockets.
Avatar billede arne_v Ekspert
24. juli 2003 - 17:55 #35
Og med hensyn til forskellen på Socket og SSLSocket, så burde der ikke
være nogen funktionel forskel.

Men. SSLSocket må være en lile smule langsommere. Og det kan måske for et
latent timing problem frem i lyset.

Kun et gæt.

Men medmnidre der er fejl i SSLSocket implementeringen, så må der jo
være et eller andet der trigger forskellen.
Avatar billede trp79 Nybegynder
24. juli 2003 - 18:08 #36
Den var null!!!
Jeg har nu fundet fejlen, men jeg forstår faktisk ikke at den var null...

public class Klient
{
    static SSLSocket socket;
    static DataInputStream inStream;
    static PrintStream outStream;
    static String brugernavn;
    static String password;
    private ObjectOutputStream output;        //Bruges til at sende arraylister med
    private javax.swing.JLabel jLStatus;    //modtages fra Upload.java således at brugeren via en jlabel kan følge med i statusen af uploadingen.
    private boolean connected=false;
    private JProgressBar jProgressBar;        //så man kan følge med hvor langt upload tingen er nået.
    private int a=0;                        //en tæller til jProgressBar

    Klient(String serverAdr, String brugernavn, String password, JLabel jLStatus, JProgressBar jProgressBar)
    {
        this.brugernavn = brugernavn;
        this.password = password;
        this.jLStatus = jLStatus;
        this.jProgressBar = jProgressBar;
........
........mere kode
        SSLSocket socket = (SSLSocket)sslFact.createSocket(serverAdr, 8205);


øverst oppe i kode stykket erklære jeg: "static SSLSocket socket;"
og i sidste linie i kodestykket erklære jeg: "        SSLSocket socket = (SSLSocket)sslFact.createSocket(serverAdr, 8205);"

Det bevirkede at "socket" blev null, men hvorfor?
Nu virker det, efter at jeg har fjerne SSLSocket fra den sidste linie :o)
Avatar billede trp79 Nybegynder
24. juli 2003 - 18:09 #37
Mange tak for hjælpen - det er jo forrygende at det bare funker nu!
Avatar billede arne_v Ekspert
24. juli 2003 - 18:13 #38
Det er vel ikek så overraskende.

Du laver en klasse variabel socket. Den får værdien null når klassen
loades.

Så kalder du en constructor. Den constructor laver en lokal varibale ved
navn socket, creater en SSLSocket og assigner den til den lokale variabel.
Klasse variablen er stadigvæk null. Nå du forlader constructoren så
garbage collectes den lokale variabel og SSL socketen lukkes.

Senere bruger du så klasse variablen som stadigvæk er null.
Avatar billede trp79 Nybegynder
25. juli 2003 - 09:03 #39
Ja selvfølgelig.
Spørgsmålet gik efterhånden en del væk fra overskriften og du har vel også brugt en del tid på det? Var det ikke fair med et par extra points til dig?
Avatar billede trp79 Nybegynder
25. juli 2003 - 09:11 #40
Der er lidt extra points her:
http://www.eksperten.dk/spm/379672

Lige et afsluttende spøgsmål: Certifikatet sendes fra server til klient, derfor skal certifikatet vel ikke være installeret (ved at eksekverer/dobbeltklikke cert.cer)? Det er fordi mit prog virker forrygende når jeg køre på localhost, men når jeg tester det på et netværk så kan der ikke oprettes forbindelse :o(
Avatar billede arne_v Ekspert
25. juli 2003 - 09:33 #41
Jge takker for point.
Avatar billede arne_v Ekspert
25. juli 2003 - 09:35 #42
Jeg er ikke helt sikker på at jeg forstår problematikken.

Det virker med client og server på samme system men ikke med client
og server på 2 forskellige systemer ?
Avatar billede trp79 Nybegynder
25. juli 2003 - 09:44 #43
Jeg det virker med server og klient på localhost men ikke hvis jeg prøver på et lan... det kan slet ikke opnås forbindelse.
Avatar billede arne_v Ekspert
25. juli 2003 - 10:25 #44
Hvilken fejl får du ?

"ikke opnås forbindelse" er det "Connection refused" ?

Har du kun certfikatet på server maskinen eller både på client og
server maskine ?
Avatar billede trp79 Nybegynder
25. juli 2003 - 12:47 #45
Det var underligt... af en eller anden underlig grund havde windows gemt filen "truststore" som "truststore.dat" og "keystore" som "keystore.dat" da jeg mailede dem til den anden pc- derfor ville den selvfølgelig ikke. Måske jeg skulle smide dem ind i jar filen, så det problem ikke opstår igen....
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester