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.URL
kelas 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 URL
pelaksanaan kelas Java standard . Akibatnya, jika anda berusaha membina URL
objek dengan rentetan yang menentukan HTTPS sebagai protokol, MalformedURLException
akan dilemparkan.
Nasib baik, untuk mengatasi kekangan itu, spesifikasi Java menyediakan kemampuan untuk memilih pengendali aliran alternatif untuk URL
kelas. 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 wininet
pakejnya. 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 Security
objek 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, MalformedURLException
tidak 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 SSLException
dengan 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.wininet
pakej.
Anda boleh menetapkan pengendali aliran dalam persekitaran JView dengan memanggil satu kaedah statik di URL
kelas:
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, setURLStreamHandlerFactory
kaedah 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.wininet
pakej 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, WinInetStreamHandlerFactory
adalah "... 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.winint
pakej Microsoft , komunikasi yang selamat dapat dilakukan dari kebanyakan platform dengan hanya beberapa baris kod.
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 theHttpMessage
class written by Jason Hunter, author of Java Servlet Programming (O'Reilly & Associates). Look forHttpsMessage
in the upcoming second edition of his book. If you wish to use that class as intended, you'll need to download and install thecom.oreilly.servlets
package. Thecom.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.