Petua Java 96: Gunakan HTTPS dalam kod klien Java anda

Sekiranya anda pernah mencuba untuk melaksanakan komunikasi selamat antara klien Java dan pelayan HTTPS (HyperText Transfer Protocol Secure), anda mungkin telah mengetahui bahawa java.net.URLkelas standard tidak menyokong protokol HTTPS. Pelaksanaan persamaan dari sisi pelayan agak mudah. Hampir mana-mana pelayan Web yang tersedia hari ini menyediakan mekanisme untuk meminta data, menggunakan HTTPS. Setelah anda menyediakan pelayan Web anda, penyemak imbas apa pun boleh meminta maklumat yang selamat dari pelayan anda hanya dengan menetapkan HTTPS sebagai protokol untuk URL. Sekiranya anda belum menyediakan pelayan HTTPS, anda boleh menguji kod pelanggan anda dengan hampir semua Laman Web HTTPS di Internet. Bahagian Sumber mengandungi senarai pendek calon yang boleh anda gunakan untuk tujuan tersebut.

Namun, dari sudut pandang pelanggan, kesederhanaan S pada akhir HTTP yang sudah biasa adalah menipu. Penyemak imbas sebenarnya melakukan banyak kerja di belakang layar untuk memastikan bahawa tidak ada yang mengganggu atau memantau maklumat yang anda minta. Ternyata, algoritma untuk melakukan penyulitan untuk HTTPS dipatenkan oleh RSA Security (sekurang-kurangnya beberapa bulan lagi). Penggunaan algoritma itu telah dilesenkan oleh pengeluar penyemak imbas tetapi tidak dilesenkan oleh Sun Microsystems untuk dimasukkan dalam URLpelaksanaan kelas Java standard . Akibatnya, jika anda berusaha membina URLobjek dengan rentetan yang menentukan HTTPS sebagai protokol, MalformedURLExceptionakan dilemparkan.

Nasib baik, untuk mengatasi kekangan itu, spesifikasi Java menyediakan kemampuan untuk memilih pengendali aliran alternatif untuk URLkelas. Walau bagaimanapun, teknik yang diperlukan untuk melaksanakannya berbeza, bergantung pada mesin maya (VM) yang anda gunakan. Untuk VM yang kompatibel dengan JDK 1.1, JView, Microsoft telah melesenkan algoritma dan menyediakan pengendali aliran HTTPS sebagai sebahagian daripada wininetpakejnya. Sun, di sisi lain, baru-baru ini merilis Java Secure Sockets Extension (JSSE) untuk VM yang serasi dengan JDK 1.2, di mana Sun juga telah melesenkan dan menyediakan pengendali aliran HTTPS. Artikel ini akan menunjukkan cara untuk melaksanakan penggunaan pengendali aliran berkemampuan HTTPS, menggunakan paket JSSE dan Microsoft wininet.

Mesin maya yang serasi dengan JDK 1.2

Teknik untuk menggunakan VM yang serasi dengan JDK 1.2 bergantung terutamanya pada Java Secure Sockets Extension (JSSE) 1.0.1. Sebelum teknik itu berfungsi, anda mesti memasang JSSE dan menambahkannya ke jalur kelas VM klien yang dimaksudkan.

Selepas anda memasang JSSE, anda mesti menetapkan sifat sistem dan menambahkan penyedia keselamatan baru ke Securityobjek kelas. Terdapat pelbagai cara untuk melakukan kedua perkara ini, tetapi untuk tujuan artikel ini, kaedah terprogram ditunjukkan:

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

Setelah membuat dua kaedah panggilan sebelumnya, MalformedURLExceptiontidak akan dilemparkan lagi dengan memanggil kod berikut:

 URL url = URL baru ("// [pelayan anda]"); 

Sekiranya anda menyambung ke port SSL standard, 443, anda mempunyai pilihan untuk menambahkan nombor port ke rentetan URL. Walau bagaimanapun, jika pelayan Web anda menggunakan port tidak standard untuk trafik SSL, anda perlu menambahkan nombor port ke rentetan URL anda seperti ini:

 URL url = URL baru ("// [pelayan anda]: 7002"); 

Satu peringatan dari teknik itu ialah URL yang merujuk kepada pelayan yang mempunyai sijil SSL yang tidak ditandatangani atau tidak sah. Dalam kes itu, usaha untuk mengambil aliran input atau output dari objek sambungan URL akan melemparkan SSLExceptiondengan mesej "rantai sijil pelayan yang tidak dipercayai." Sekiranya pelayan mempunyai sijil yang sah dan ditandatangani, tidak akan ada pengecualian.

URL url = URL baru ("// [pelayan anda]"); URLConnection con = URL.openConnection (); // SSLException dilemparkan ke sini jika sijil pelayan tidak sah con.getInputStream ();

Penyelesaian yang jelas untuk masalah itu adalah mendapatkan sijil yang ditandatangani untuk pelayan anda. Namun, salah satu URL berikut juga dapat memberikan solusi: "Java Secure Socket Extension 1.0.2 Changes" (Sun Microsystems) atau forum Sun's Java Developer Connection.

Microsoft JView

Kerana sebagian perselisihan yang sedang berlangsung antara Microsoft dan Sun mengenai pelesenan Java untuk digunakan pada platform Windows, Microsoft JView VM saat ini hanya mematuhi JDK 1.1. Oleh itu, teknik yang dijelaskan di atas tidak akan berfungsi untuk klien yang menjalankan di JView, kerana JSSE memerlukan sekurang-kurangnya VM serasi 1.2.2. Namun, cukup mudah, Microsoft menyediakan pengendali aliran berkemampuan HTTPS sebagai sebahagian daripada com.ms.net.wininetpakej.

Anda boleh menetapkan pengendali aliran dalam persekitaran JView dengan memanggil satu kaedah statik di URLkelas:

 URL.setURLStreamHandlerFactory (com.ms.net.wininet.WininetStreamHandlerFactory baru ()); 

Setelah membuat panggilan kaedah sebelumnya,

MalformedURLException

tidak akan dilemparkan lagi dengan memanggil kod berikut:

 URL url = URL baru ("// [pelayan anda]"); 

Terdapat dua peringatan yang berkaitan dengan teknik itu. Pertama, menurut dokumentasi JDK, setURLStreamHandlerFactorykaedah tersebut boleh dipanggil paling banyak sekali dalam VM tertentu. Percubaan berikutnya untuk memanggil kaedah itu akan membuang Error. Kedua, seperti halnya dengan penyelesaian 1.2 VM, anda harus berhati-hati ketika menggunakan URL yang merujuk kepada pelayan dengan sijil SSL yang tidak ditandatangani atau tidak sah. Seperti halnya sebelumnya, masalah terjadi ketika upaya dilakukan untuk mengambil aliran input atau output dari objek sambungan URL. Namun, bukannya membuang SSLException, pengendali aliran Microsoft membuang standard IOException.

URL url = URL baru ("// [pelayan anda]"); URLConnection con = url.openConnection (); // IOException dilemparkan ke sini jika sijil pelayan tidak sah con.getInputStream ();

Sekali lagi, penyelesaian yang jelas untuk masalah itu adalah dengan mencuba komunikasi HTTPS hanya dengan pelayan yang mempunyai sijil yang ditandatangani dan sah. Walau bagaimanapun, JView menawarkan satu pilihan lain. Segera sebelum mengambil input atau aliran output dari objek sambungan URL, Anda dapat memanggil setAllowUserInteraction(true)objek sambungan. Itu akan menyebabkan JView memaparkan mesej yang memberi peringatan kepada pengguna bahawa sijil pelayan tidak sah, tetapi memberikannya pilihan untuk meneruskannya. Perlu diingat, bagaimanapun, bahawa mesej tersebut mungkin masuk akal untuk aplikasi desktop, tetapi mempunyai kotak dialog yang muncul di pelayan anda untuk apa-apa selain daripada tujuan penyahpepijatan mungkin tidak dapat diterima.

Catatan: Anda juga boleh memanggil setAllowUserInteraction()kaedah dalam VM yang serasi dengan JDK 1.2. Namun, dalam menggunakan 1.2 VM Sun (dengan kode ini diuji), tidak ada dialog yang ditampilkan walaupun harta itu ditetapkan menjadi benar.

URL url = URL baru ("// [pelayan anda]"); URLConnection con = url.openConnection (); // menyebabkan VM memaparkan dialog ketika menyambungkan // ke pelayan yang tidak dipercayai con.setAllowUserInteraction (true); con.getInputStream ();

The com.ms.net.wininetpakej nampaknya dipasang dan diletakkan di atas classpath sistem secara lalai pada Windows NT 4.0, Windows 2000, dan sistem Windows 9x. Juga, menurut dokumentasi Microsoft JDK, WinInetStreamHandlerFactoryadalah "... pengendali yang sama yang dipasang secara lalai ketika menjalankan applet."

Kebebasan platform

Walaupun kedua-dua teknik tersebut telah saya jelaskan merangkumi sebahagian besar platform di mana klien Java anda boleh berjalan, klien Java anda mungkin perlu berjalan pada kedua-dua VM JDK 1.1- dan JDK 1.2. "Tulis sekali, jalankan ke mana sahaja," ingat? Ternyata, menggabungkan kedua teknik sehingga pengendali yang sesuai dimuat bergantung pada VM, cukup mudah. Kod berikut menunjukkan satu cara untuk menyelesaikannya:

String strVendor = System.getProperty ("java.vendor"); String strVersion = System.getProperty ("java.version"); // Menganggap rentetan versi sistem dari bentuk: //[major].[minor].[release] (mis. 1.2.2) Double dVersion = Double baru (strVersion.substring (0, 3)); // Jika kita berjalan di lingkungan MS, gunakan pengendali aliran MS. if (-1 <strVendor.indexOf ("Microsoft")) {cuba {Class clsFactory = Class.forName ("com.ms.net.wininet.WininetStreamHandlerFactory"); jika (null! = clsFactory) URL.setURLStreamHandlerFactory ((URLStreamHandlerFactory) clsFactory.newInstance ()); } tangkap (ClassNotFoundException cfe) {buang Pengecualian baru ("Tidak dapat memuat pengendali aliran Microsoft SSL" + ". Periksa classpath." + cfe.toString ());} // Sekiranya kilang pengendali aliran telah // berjaya disiapkan // pastikan bendera kita diset dan makan tangkapan ralat (Kesalahan ralat) {m_bStreamHandlerSet = true;}} // Sekiranya kita berada dalam lingkungan Java yang normal, // cuba gunakan pengendali JSSE. // CATATAN: JSSE memerlukan 1.2 atau lebih baik jika (1.2 <= dVersion.doubleValue ()) {System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol "); cuba {// jika kita mempunyai penyedia JSSE yang tersedia, // dan belum disetel //, tambahkan sebagai penyedia baru ke kelas Keselamatan. Class clsFactory = Class.forName ("com.sun.net.ssl.internal.ssl.Provider"); jika ((null! = clsFactory) && (null == Security.getProvider ("SunJSSE"))) Security.addProvider ((Penyedia) clsFactory.newInstance ());} tangkapan (ClassNotFoundException cfe) {lemparkan Pengecualian baru ("Tidak dapat memuat pengendali aliran SSL JSSE." + "Periksa classpath." + cfe.toString ()); }}

What about applets?

Performing HTTPS-based communication from within an applet seems like a natural extension of scenarios described above. In reality, it's even easier in most cases. In 4.0 and later versions of Netscape Navigator and Internet Explorer, HTTPS is enabled by default for their respective VMs. Therefore, if you want to create an HTTPS connection from within your applet code, simply specify HTTPS as your protocol when creating an instance of the URL class:

 URL url = new URL("//[your server]"); 

If the client browser is running Sun's Java 2 plug-in, then there are additional limitations to how you can use HTTPS. A full discussion on using HTTPS with the Java 2 plug-in can be found on Sun's Website (see Resources).

Conclusion

Menggunakan protokol HTTPS antara aplikasi boleh menjadi cara yang cepat dan berkesan untuk mendapatkan tahap keselamatan yang wajar dalam komunikasi anda. Sayangnya, alasan bahawa ia tidak disokong sebagai bagian dari spesifikasi Java standard nampaknya lebih sah daripada teknikal. Namun, dengan munculnya JSSE dan penggunaan com.ms.net.winintpakej Microsoft , komunikasi yang selamat dapat dilakukan dari kebanyakan platform dengan hanya beberapa baris kod.

Matt Towers, eBozo yang digambarkan sendiri, baru-baru ini meninggalkan kedudukan pengembangannya dengan Visio. Sejak itu dia bergabung dengan permulaan Internet, PredictPoint.com, di Seattle, Wash., Di mana dia bekerja sebagai pemaju Java sepenuh masa.

Ketahui lebih lanjut mengenai topik ini

  • The source code zip file for this article contains the platform-independent code shown above implemented in a class called HttpsMessage. HttpsMessage is intended as a subclass to the HttpMessage class written by Jason Hunter, author of Java Servlet Programming (O'Reilly & Associates). Look for HttpsMessage in the upcoming second edition of his book. If you wish to use that class as intended, you'll need to download and install the com.oreilly.servlets package. The com.oreilly.servlets package and corresponding source code can be found on Hunter's Website

    //www.servlets.com

  • You can also download the source zip file

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

  • Here are a few good Webpages for testing HTTPS communication:
  • //www.verisign.com/
  • //happiness.dhs.org/
  • //www.microsoft.com
  • //www.sun.com
  • //www.ftc.gov
  • More information on the JSSE as well as the downloadable bits and installation instructions can be found on Sun's Website

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

  • A description of how to use some JSSE services, including the technique described above, can be found in "Secure Networking in Java" by Jonathan Knudsen on the O'Reilly Website

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

  • More information on WininetStreamHandlerFactory class can be found in the Microsoft JSDK documentation

    //www.microsoft.com/java/sdk/. In addition, the Microsoft knowledge base also publishes "PRBAllowing the URL class to access HTTPS in Applications"

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

  • For more information on using HTTPS with the Java 2 plug-in, see "How HTTPS Works in Java Plug-In" on Sun's Website

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

Kisah ini, "Petua Java 96: Gunakan HTTPS dalam kod klien Java anda" pada awalnya diterbitkan oleh JavaWorld.