Προγραμματισμός

Συμβουλή Java 96: Χρησιμοποιήστε HTTPS στον κώδικα πελάτη Java

Εάν έχετε προσπαθήσει ποτέ να εφαρμόσετε ασφαλή επικοινωνία μεταξύ ενός προγράμματος-πελάτη Java και ενός διακομιστή HTTPS (HyperText Transfer Protocol Secure), πιθανότατα έχετε ανακαλύψει ότι το πρότυπο java.net.URL Η τάξη δεν υποστηρίζει το πρωτόκολλο HTTPS. Η υλοποίηση αυτής της εξίσωσης από την πλευρά του διακομιστή είναι αρκετά απλή. Σχεδόν οποιοσδήποτε διακομιστής Web διαθέσιμος σήμερα παρέχει έναν μηχανισμό για την υποβολή αιτημάτων δεδομένων, χρησιμοποιώντας HTTPS. Μόλις ρυθμιστεί ο διακομιστής Ιστού σας, οποιοδήποτε πρόγραμμα περιήγησης μπορεί να ζητήσει ασφαλείς πληροφορίες από τον διακομιστή σας απλώς καθορίζοντας το HTTPS ως πρωτόκολλο για τη διεύθυνση URL. Εάν δεν έχετε ήδη ρυθμίσει διακομιστή HTTPS, μπορείτε να δοκιμάσετε τον κωδικό πελάτη σας με σχεδόν οποιαδήποτε ιστοσελίδα HTTPS στο Διαδίκτυο. Η ενότητα Πόροι περιέχει μια σύντομη λίστα υποψηφίων που μπορείτε να χρησιμοποιήσετε για το σκοπό αυτό.

Ωστόσο, από την οπτική γωνία του πελάτη, η απλότητα του S στο τέλος του γνωστού HTTP παραπλανά. Το πρόγραμμα περιήγησης κάνει πραγματικά μια σημαντική δουλειά στο παρασκήνιο για να διασφαλίσει ότι κανείς δεν έχει παραβιάσει ή παρακολουθεί τις πληροφορίες που ζητήσατε. Όπως αποδεικνύεται, ο αλγόριθμος για την κρυπτογράφηση για HTTPS κατοχυρώνεται με δίπλωμα ευρεσιτεχνίας από την RSA Security (για τουλάχιστον μερικούς ακόμη μήνες). Η χρήση αυτού του αλγορίθμου έχει λάβει άδεια από κατασκευαστές προγραμμάτων περιήγησης, αλλά δεν έχει λάβει άδεια από την Sun Microsystems να συμπεριληφθεί στο τυπικό Java Διεύθυνση URL εφαρμογή τάξης. Ως αποτέλεσμα, εάν επιχειρήσετε να δημιουργήσετε ένα Διεύθυνση URL αντικείμενο με μια συμβολοσειρά που καθορίζει το HTTPS ως πρωτόκολλο, α Ελαττωματική εξαίρεση θα πετάξει.

Ευτυχώς, για την αντιμετώπιση αυτού του περιορισμού, η προδιαγραφή Java παρέχει τη δυνατότητα επιλογής εναλλακτικού χειριστή ροής για το Διεύθυνση URL τάξη. Ωστόσο, η τεχνική που απαιτείται για την εφαρμογή είναι διαφορετική, ανάλογα με την εικονική μηχανή (VM) που χρησιμοποιείτε. Για VM, JVK, συμβατό με JDK 1.1 της Microsoft, η Microsoft έχει χορηγήσει άδεια χρήσης του αλγορίθμου και παρείχε ένα χειριστή ροής HTTPS ως μέρος του οινοποιείο πακέτο. Η Sun, από την άλλη πλευρά, κυκλοφόρησε πρόσφατα την επέκταση Java Secure Sockets (JSSE) για συμβατές συσκευές VMs JDK 1.2, στις οποίες η Sun έχει επίσης παραχωρήσει άδεια και παρείχε ένα HTTPS stream handler. Αυτό το άρθρο θα δείξει πώς να εφαρμόσετε τη χρήση ενός χειριστή ροής με δυνατότητα HTTPS, χρησιμοποιώντας το JSSE και το Microsoft οινοποιείο πακέτο.

Εικονικές μηχανές συμβατές με JDK 1.2

Η τεχνική για τη χρήση VM συμβατών με JDK 1.2 βασίζεται κυρίως στην επέκταση Java Secure Sockets (JSSE) 1.0.1. Προτού λειτουργήσει αυτή η τεχνική, πρέπει να εγκαταστήσετε το JSSE και να το προσθέσετε στη διαδρομή κλάσης του εν λόγω πελάτη VM.

Αφού εγκαταστήσετε το JSSE, πρέπει να ορίσετε μια ιδιότητα συστήματος και να προσθέσετε έναν νέο πάροχο ασφαλείας στο Ασφάλεια αντικείμενο κλάσης. Υπάρχουν διάφοροι τρόποι για να κάνετε και τα δύο αυτά πράγματα, αλλά για τους σκοπούς αυτού του άρθρου, εμφανίζεται η μέθοδος μέσω προγραμματισμού:

 System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); Security.addProvider (νέο com.sun.net.ssl.internal.ssl.Provider ()); 

Αφού πραγματοποιήσατε τις προηγούμενες δύο κλήσεις μεθόδου, το Λανθασμένη εξαίρεσηURLException δεν θα πετάγεται πλέον καλώντας τον ακόλουθο κωδικό:

 URL url = νέο URL ("// [ο διακομιστής σας]"); 

Εάν συνδέεστε στην τυπική θύρα SSL, 443, έχετε την επιλογή να προσθέσετε τον αριθμό θύρας στη συμβολοσειρά URL. Ωστόσο, εάν ο διακομιστής Ιστού σας χρησιμοποιεί μια μη τυπική θύρα για επισκεψιμότητα SSL, θα πρέπει να προσθέσετε τον αριθμό θύρας στη συμβολοσειρά URL σας ως εξής:

 URL url = νέο URL ("// [ο διακομιστής σας]: 7002"); 

Μία προειδοποίηση αυτής της τεχνικής αφορά μια διεύθυνση URL που αναφέρεται σε έναν διακομιστή που διαθέτει πιστοποιητικό SSL χωρίς υπογραφή ή μη έγκυρο. Σε αυτήν την περίπτωση, μια προσπάθεια ανάκτησης της ροής εισόδου ή εξόδου από το αντικείμενο σύνδεσης της διεύθυνσης URL θα ρίξει ένα SSLException με το μήνυμα "μη αξιόπιστη αλυσίδα πιστοποιητικού διακομιστή." Εάν ο διακομιστής διαθέτει έγκυρο, υπογεγραμμένο πιστοποιητικό, δεν θα υπάρξει εξαίρεση.

 URL url = νέο URL ("// [ο διακομιστής σας]"); URLConnection con = URL.openConnection (); // SSLException ρίχνεται εδώ εάν το πιστοποιητικό διακομιστή δεν είναι έγκυρο con.getInputStream (); 

Η προφανής λύση σε αυτό το πρόβλημα είναι να λάβετε υπογεγραμμένα πιστοποιητικά για τον διακομιστή σας. Ωστόσο, μία από τις ακόλουθες διευθύνσεις URL μπορεί επίσης να παρέχει μια λύση: "Java Secure Socket Extension 1.0.2 Changes" (Sun Microsystems) ή φόρουμ της Sun Developer Java Connection.

Microsoft JView

Λόγω εν μέρει της συνεχιζόμενης διαφωνίας μεταξύ της Microsoft και της Sun σχετικά με την αδειοδότηση της Java για χρήση σε πλατφόρμες Windows, το Microsoft JView VM προς το παρόν είναι μόνο συμβατό με το JDK 1.1. Επομένως, η τεχνική που περιγράφεται παραπάνω δεν θα λειτουργήσει για πελάτες που εκτελούνται στο JView, καθώς το JSSE απαιτεί τουλάχιστον 1.2.2 συμβατό VM. Ωστόσο, αρκετά βολικά, η Microsoft παρέχει ένα πρόγραμμα χειρισμού ροής με δυνατότητα HTTPS ως μέρος του com.ms.net.wininet πακέτο.

Μπορείτε να ρυθμίσετε το χειριστή ροής σε περιβάλλον JView καλώντας μια στατική μέθοδο στο Διεύθυνση URL τάξη:

 URL.setURLStreamHandlerFactory (νέο com.ms.net.wininet.WininetStreamHandlerFactory ()); 

Αφού πραγματοποιήσατε την προηγούμενη κλήση μεθόδου, το

Ελαττωματική εξαίρεση

δεν θα πετάγεται πλέον καλώντας τον ακόλουθο κωδικό:

 URL url = νέο URL ("// [ο διακομιστής σας]"); 

Υπάρχουν δύο προειδοποιήσεις που σχετίζονται με αυτήν την τεχνική. Πρώτον, σύμφωνα με την τεκμηρίωση JDK, το setURLStreamHandlerFactory μέθοδος μπορεί να καλείται το πολύ μία φορά σε ένα δεδομένο VM. Οι επόμενες προσπάθειες να καλέσετε αυτήν τη μέθοδο θα ρίξουν ένα Λάθος. Δεύτερον, όπως συμβαίνει με τη λύση 1.2 VM, πρέπει να είστε προσεκτικοί όταν χρησιμοποιείτε μια διεύθυνση URL που αναφέρεται σε διακομιστή με πιστοποιητικό SSL χωρίς υπογραφή ή μη. Όπως με την προηγούμενη περίπτωση, προκύπτουν προβλήματα όταν γίνεται προσπάθεια ανάκτησης της ροής εισόδου ή εξόδου από το αντικείμενο σύνδεσης της διεύθυνσης URL. Ωστόσο, αντί να ρίχνουμε ένα SSLException, ο χειριστής ροής της Microsoft ρίχνει ένα πρότυπο IOException.

 URL url = νέο URL ("// [ο διακομιστής σας]"); URLConnection con = url.openConnection (); // IOException ρίχνεται εδώ εάν το πιστοποιητικό διακομιστή δεν είναι έγκυρο con.getInputStream (); 

Και πάλι, η προφανής λύση σε αυτό το πρόβλημα είναι να επιχειρήσετε επικοινωνία HTTPS μόνο με διακομιστές που έχουν υπογεγραμμένο, έγκυρο πιστοποιητικό. Ωστόσο, το JView προσφέρει μια άλλη επιλογή. Αμέσως πριν από την ανάκτηση της ροής εισόδου ή εξόδου από το αντικείμενο σύνδεσης της διεύθυνσης URL, μπορείτε να καλέσετε setAllowUserInteraction (αληθινό) στο αντικείμενο σύνδεσης. Αυτό θα αναγκάσει το JView να εμφανίσει ένα μήνυμα που προειδοποιεί τον χρήστη ότι τα πιστοποιητικά του διακομιστή δεν είναι έγκυρα, αλλά του δίνει τη δυνατότητα να συνεχίσει ούτως ή άλλως. Λάβετε υπόψη, ωστόσο, ότι τέτοια μηνύματα μπορεί να είναι λογικά για μια εφαρμογή επιτραπέζιου υπολογιστή, αλλά η εμφάνιση κουτιών διαλόγου στον διακομιστή σας για οτιδήποτε άλλο εκτός από σκοπούς εντοπισμού σφαλμάτων είναι πιθανώς απαράδεκτη.

Σημείωση: Μπορείτε επίσης να καλέσετε το setAllowUserInteraction () μέθοδος σε συμβατά με JDK 1.2 VM. Ωστόσο, κατά τη χρήση 1.2 VM της Sun (με την οποία δοκιμάστηκε αυτός ο κωδικός), δεν εμφανίζονται διαλόγοι ακόμη και όταν η ιδιότητα έχει οριστεί σε true.

 URL url = νέο URL ("// [ο διακομιστής σας]"); URLConnection con = url.openConnection (); // προκαλεί το VM να εμφανίζει ένα παράθυρο διαλόγου κατά τη σύνδεση // σε μη αξιόπιστους διακομιστές con.setAllowUserInteraction (true); con.getInputStream (); 

ο com.ms.net.wininet Το πακέτο φαίνεται να έχει εγκατασταθεί και να τοποθετηθεί στο classpath του συστήματος από προεπιλογή στα συστήματα Windows NT 4.0, Windows 2000 και Windows 9x. Επίσης, σύμφωνα με την τεκμηρίωση του Microsoft JDK, WinInetStreamHandlerFactory είναι "... ο ίδιος χειριστής που εγκαθίσταται από προεπιλογή κατά την εκτέλεση μικροεφαρμογών."

Ανεξαρτησία πλατφόρμας

Παρόλο που και οι δύο αυτές τεχνικές που περιέγραψα καλύπτουν τις περισσότερες από τις πλατφόρμες στις οποίες μπορεί να εκτελείται ο υπολογιστής-πελάτης Java, ο υπολογιστής-πελάτης Java ενδέχεται να χρειαστεί να εκτελεστεί σε δύο συμβατές με JDK 1.1- και JDK 1.2 "Γράψτε μία φορά, τρέξτε οπουδήποτε", θυμάστε; Όπως αποδεικνύεται, ο συνδυασμός αυτών των δύο τεχνικών έτσι ώστε να φορτώνεται ο κατάλληλος χειριστής ανάλογα με το VM, είναι αρκετά απλός. Ο ακόλουθος κώδικας δείχνει έναν τρόπο να το κάνετε:

 String strVendor = System.getProperty ("java.vendor"); String strVersion = System.getProperty ("java.version"); // Υποθέτει μια συμβολοσειρά έκδοσης συστήματος της φόρμας: //[major].[minor].[release] (π.χ. 1.2.2) Double dVersion = new Double (strVersion.substring (0, 3)); // Εάν εκτελούμε σε περιβάλλον MS, χρησιμοποιήστε το πρόγραμμα διαχείρισης ροής MS. if (-1 <strVendor.indexOf ("Microsoft")) {δοκιμάστε {Class clsFactory = Class.forName ("com.ms.net.wininet.WininetStreamHandlerFactory"); if (null! = clsFactory) URL.setURLStreamHandlerFactory ((URLStreamHandlerFactory) clsFactory.newInstance ()); } catch (ClassNotFoundException cfe) {ρίξτε νέα εξαίρεση ("Δεν είναι δυνατή η φόρτωση του χειριστή ροής Microsoft SSL" + ". Ελέγξτε το classpath." + cfe.toString ()); } // Εάν το εργοστάσιο χειριστή ροής // έχει ήδη ρυθμιστεί επιτυχώς // βεβαιωθείτε ότι η σημαία μας έχει ρυθμιστεί και φάτε το σφάλμα σφάλματος (Error err) {m_bStreamHandlerSet = true;}} // Εάν είμαστε σε ένα κανονικό περιβάλλον Java // προσπαθήστε να χρησιμοποιήσετε το πρόγραμμα χειρισμού JSSE. // ΣΗΜΕΙΩΣΗ: Το JSSE απαιτεί 1,2 ή καλύτερα αλλού εάν (1.2 <= dVersion.doubleValue ()) {System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol "); δοκιμάστε {// εάν διαθέτουμε τον πάροχο JSSE, // και δεν έχει ήδη καθοριστεί //, προσθέστε τον ως νέα παροχή στην κλάση ασφαλείας. Class clsFactory = Class.forName ("com.sun.net.ssl.internal.ssl.Provider"); if ((null! = clsFactory) && (null == Security.getProvider ("SunJSSE"))) Security.addProvider ((Provider) clsFactory.newInstance ()); } catch (ClassNotFoundException cfe) {ρίξτε νέα εξαίρεση ("Δεν είναι δυνατή η φόρτωση του χειριστή ροής JSSE SSL." + "Έλεγχος classpath." + cfe.toString ()); }} 

Τι γίνεται με τις μικροεφαρμογές;

Η εκτέλεση επικοινωνίας που βασίζεται σε HTTPS από μια μικροεφαρμογή φαίνεται σαν μια φυσική επέκταση των σεναρίων που περιγράφονται παραπάνω. Στην πραγματικότητα, είναι ακόμη πιο εύκολο στις περισσότερες περιπτώσεις. Σε εκδόσεις 4.0 και νεότερες εκδόσεις του Netscape Navigator και του Internet Explorer, το HTTPS είναι ενεργοποιημένο από προεπιλογή για τα αντίστοιχα VM τους. Επομένως, εάν θέλετε να δημιουργήσετε μια σύνδεση HTTPS από τον κώδικα της μικροεφαρμογής σας, απλώς ορίστε το HTTPS ως πρωτόκολλο κατά τη δημιουργία μιας παρουσίας του Διεύθυνση URL τάξη:

 URL url = νέο URL ("// [ο διακομιστής σας]"); 

Εάν το πρόγραμμα περιήγησης πελάτη εκτελεί την προσθήκη Java 2 της Sun, τότε υπάρχουν πρόσθετοι περιορισμοί στον τρόπο χρήσης του HTTPS. Μια πλήρης συζήτηση σχετικά με τη χρήση του HTTPS με την προσθήκη Java 2 μπορείτε να βρείτε στον ιστότοπο της Sun (βλ. Πόρους).

συμπέρασμα

Η χρήση του πρωτοκόλλου HTTPS μεταξύ εφαρμογών μπορεί να είναι ένας γρήγορος και αποτελεσματικός τρόπος για να αποκτήσετε ένα λογικό επίπεδο ασφάλειας στην επικοινωνία σας. Δυστυχώς, οι λόγοι που δεν υποστηρίζονται ως μέρος της τυπικής προδιαγραφής Java φαίνεται να είναι πιο νόμιμοι παρά τεχνικοί. Ωστόσο, με την έλευση του JSSE και τη χρήση των Microsoft com.ms.net.winint πακέτο, η ασφαλής επικοινωνία είναι δυνατή από τις περισσότερες πλατφόρμες με λίγες μόνο γραμμές κώδικα.

Ο Matt Towers, ένα αυτο-περιγραφόμενο eBozo, εγκατέλειψε πρόσφατα τη θέση του με τον Visio. Από τότε εντάχθηκε σε μια εκκίνηση στο Διαδίκτυο, το PredictPoint.com, στο Σιάτλ της Ουάσινγκτον, όπου εργάζεται ως προγραμματιστής Java πλήρους απασχόλησης.

Μάθετε περισσότερα σχετικά με αυτό το θέμα

  • Το αρχείο zip του πηγαίου κώδικα για αυτό το άρθρο περιέχει τον ανεξάρτητο από την πλατφόρμα κωδικό που εμφανίζεται παραπάνω και έχει εφαρμοστεί σε μια κατηγορία που ονομάζεται HttpsMessage. HttpsMessage προορίζεται ως υποκατηγορία του HttpMessage τάξη γραμμένη από τον Jason Hunter, συγγραφέα του Προγραμματισμός Java Servlet (O'Reilly & Associates). Ψάχνω HttpsMessage στην επερχόμενη δεύτερη έκδοση του βιβλίου του. Εάν θέλετε να χρησιμοποιήσετε αυτήν την τάξη όπως προορίζεται, θα πρέπει να κάνετε λήψη και εγκατάσταση του com.oreilly.servlets πακέτο. ο com.oreilly.servlets πακέτο και αντίστοιχος πηγαίος κώδικας μπορείτε να βρείτε στον ιστότοπο της Hunter

    //www.servlets.com

  • Μπορείτε επίσης να κατεβάσετε το αρχείο zip προέλευσης

    //images.techhive.com/downloads/idge/imported/article/jvw/2000/06/httpsmessage.zip

  • Ακολουθούν μερικές καλές ιστοσελίδες για τη δοκιμή επικοινωνίας HTTPS:
  • //www.verisign.com/
  • //happiness.dhs.org/
  • //www.microsoft.com
  • //www.sun.com
  • //www.ftc.gov
  • Περισσότερες πληροφορίες σχετικά με το JSSE καθώς και τα κομμάτια που μπορείτε να κατεβάσετε και τις οδηγίες εγκατάστασης μπορείτε να βρείτε στον ιστότοπο της Sun

    //java.sun.com/products/jsse/.

  • Μια περιγραφή του τρόπου χρήσης ορισμένων υπηρεσιών JSSE, συμπεριλαμβανομένης της τεχνικής που περιγράφεται παραπάνω, μπορείτε να βρείτε στο "Secure Networking in Java" από τον Jonathan Knudsen στον ιστότοπο του O'Reilly

    //java.oreilly.com/bite-size/java_1099.html

  • Περισσότερες πληροφορίες για WininetStreamHandlerFactory μπορείτε να βρείτε στην τεκμηρίωση του Microsoft JSDK

    //www.microsoft.com/java/sdk/. Επιπλέον, η βάση γνώσεων της Microsoft δημοσιεύει επίσης "PRBA επιτρέποντας στην κλάση URL να έχει πρόσβαση στο HTTPS στις εφαρμογές"

    //support.microsoft.com/support/kb/articles/Q191/1/20.ASP

  • Για περισσότερες πληροφορίες σχετικά με τη χρήση HTTPS με την προσθήκη Java 2, ανατρέξτε στην ενότητα "Πώς λειτουργεί το HTTPS στην προσθήκη Java" στον ιστότοπο της Sun

    //java.sun.com/products/plugin/1.2/docs/https.html

Αυτή η ιστορία, "Συμβουλή Java 96: Χρήση HTTPS στον κώδικα πελάτη Java" δημοσιεύθηκε αρχικά από την JavaWorld.

$config[zx-auto] not found$config[zx-overlay] not found