Java tip 96: Use https to write client programs
How to Use https in standard URL classes
By Matt towers
Summary
Using HTTPS (Hypertext Transfer Protocol Secure Hypertext Transfer Protocol) is not as simple and straightforward as you think. If you have tried secure communication between the Java client and the https server, you may notice that the standard java.net. url class does not support HTTPS. This article will show you how to use JDK 1.2-compatible virtual machine or Microsoft JDK 1.1-compatible JView to overcome these restrictions.
If you have tried secure communication between a Java client and an HTTPS (Secure Hypertext Transfer Protocol) server, you may notice the standardjava.net.URL
Class does not support HTTPS protocol. The method for the server to solve this problem is very simple and clear. Today, almost all Web servers use the HTTPS protocol to query data. Once your server is configured, any browser simply needs to specify the protocol in the URL address as https, so that it can perform information query securely on your server. If you have not set up an https server, you can test your client code on almost all HTTPS webpages on the Internet. The document section provides a list of server addresses that can be used for HTTPS communication testing.
However, from the client's point of view, simply adding "S" after the familiar HTTP can achieve secure communication. This simplicity is full of confusion. In fact, the browser has done a lot of work in the background to ensure that no one has tampered with or eavesdropped on the request data you sent. However, the algorithms used by https for encryption are patents owned by RSA Security (this situation lasts for at least a few months ). The encryption algorithm is licensed by the browser manufacturer, but sum Microsystems does not agree to bind it to the standardJava URL
Class implementation. This causes when you create a URL object, if you specify the Protocol as https,MalformedURLException
Exception.
Fortunately, to address this limitation, the Java specification providesURL
Class. However, when you use different virtual machines, the implementation of this technology is also different. In Microsoft's JDK 1.1-compatible Virtual Machine JView, Microsoft licensed the encryption algorithm and provided an HTTPS stream handle as itswininet
Part of the package. Sun recently released the Java Secure Sockets extension (JSSE) for its JDK 1.2-compatible virtual machine, which permits and provides HTTPS stream handles in JSSE. This article will elaborate on how to use JSSE and Microsoft'swininet
To implement the HTTPS stream handle.
JDK 1.2-compatible Virtual Machine
The use of HTTPS in JDK 1.2-compatible virtual machines mainly relies on Java Secure Sockets extension (JSSE) 1.0.1. You must install JSSE and add it to the class path of the client Virtual Machine to use this technology.
After JSSE is installed, you must set a system attribute to add a new security providerSecurity
Class Object. There are several methods to fulfill this requirement. In view of the purpose of this article, we will introduce a practical method:
System.setProperty("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
After the preceding two functions are called, no Throttling is triggered when the code shown below is run.MalformedURLException
Exception:
URL url = new URL("https://[your server]");
If you connect to standard SSL port 443, you can ignore the option of adding a port number after the URL string. However, if the web server you connect uses a non-standard port for SSL communication, you need to add the port number after the URL string as follows:
URL url = new URL("https://[your server]:7002");
Some servers may have no signature or illegal SSL certificates. If the URL of this type of server is involved, you need to pay attention to this method. In this case, if you try to retrieve the input or output stream from the URL Connection object (such as running the following code),SSLException
Exception, and the message "untrusted server CER chain." is displayed. If the server has a valid and signed certificate, no exception is thrown.
URL url = new URL("https://[your server]");
URLConnection con = URL.openConnection();
//SSLException thrown here if server certificate is invalid
con.getInputStream();
The most obvious solution to the above problem is to obtain a signature certificate for your server. While Java developer connectin forums sets up a workspace for this problem, you can find their related information in this URL: http://forum.java.sun.com/forum? 14 @. 787ad8de.
Microsoft Jview
Microsoft and Sun argue over the license to use Java on Windows platforms. Microsoft's JView virtual machine is only based on JDK 1.1-compliant. JSSE requires a virtual machine version 1.2.2-compatible or later. Therefore, the above method is not applicable to clients running on JView. However, Microsoft also provides a convenient HTTPS stream handle.com.ms.net.wininet
Part of the package.
In the JView environmentURL
Class calls a simple static function to set the HTTPS stream handle:
URL.setURLStreamHandlerFactory(new
com.ms.net.wininet.WininetStreamHandlerFactory());
After executing the above function call, running the following code will not throwMalformedURLException
Exception:
URL url = new URL("https://[your server]");
Pay attention to two points when using this method. First, according to the JDK documentation,serURLStreamHandlerFactory
A function can be called only once on a virtual machine. Subsequent calls will generateError
. Second, as stated in the 1.2 Virtual Machine solution, exercise caution when using URLs that direct to servers without signatures or invalid certificates. As described earlier, in this case, an error occurs when you try to retrieve the input or output data stream from the connection object of the URL address. However, Microsoft throws a standard stream handle.IOExceptiony
Exception insteadSSLException
.
URL url = new URL("https://[your server]");
URLConnection con = url.openConnection();
//IOException thrown here if server certificate is invalid
con.getInputStream();
Similarly, the most obvious solution to this problem is to communicate with only those servers with signatures and legal certificates. However, JView also provides another option. You can call the connection objectsetAllowUserInteraction(true)
Function. When JView is running, a message is displayed, notifying you that the server certificate is invalid. You can choose whether to continue. Always remember that such messages are reasonable in desktop applications, except for the purpose of debugging, it may be undesirable to bring up a message box on your server in any situation.
Note: You can also callsetAllowUserInteraction()
Function. However, on Sun's 1.2 VM (test the following code), the message box is not displayed even if the parameter of this function is set to true.
URL url = new URL("https://[your server]");
URLConnection con = url.openConnection();
//causes the VM to display a dialog when connecting
//to untrusted servers
con.setAllowUserInteraction(true);
con.getInputStream();
In Windows NT4.0, Windows2000, and Windows9x operating systems,com.ms.net.wininet
Package is installed to the system path by default. In addition, according to Microsoft's JDK documentation,WinInetStreamHandlerFactory
Yes "... The same handler that is installed by default when running applets. ", that is, when the applet is run, the same stream handle will be installed by default.
Platform independence
Although the above two methods cover the platforms where most Java client programs may run, your Java client programs may need to run correctly on JDK 1.1 and JDK 1.2-compliant virtual machines. "Write once, run anywhere," remember? It is natural to think of combining these two methods to execute corresponding processing handles based on the running Virtual Machine. The following code shows a method to achieve this goal:
String strVendor = System.getProperty("java.vendor");
String strVersion = System.getProperty("java.version");
//Assumes a system version string of the form:
//[major].[minor].[release] (eg. 1.2.2)
Double dVersion = new Double(strVersion.substring(0, 3));
//If we are running in a MS environment, use the MS stream handler.
if( -1 < strVendor.indexOf("Microsoft") )
{
try
{
Class clsFactory =
Class.forName("com.ms.net.wininet.WininetStreamHandlerFactory" );
if ( null != clsFactory )
URL.setURLStreamHandlerFactory(
(URLStreamHandlerFactory)clsFactory.newInstance());
}
catch( ClassNotFoundException cfe )
{
throw new Exception("Unable to load the Microsoft SSL " +
"stream handler. Check classpath." + cfe.toString());
}
//If the stream handler factory has
//already been successfully set
//make sure our flag is set and eat the error
catch( Error err ){m_bStreamHandlerSet = true;}
}
//If we are in a normal Java environment,
//try to use the JSSE handler.
//NOTE: JSSE requires 1.2 or better
else if( 1.2 <= dVersion.doubleValue() )
{
System.setProperty("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
try
{
//if we have the JSSE provider available,
//and it has not already been
//set, add it as a new provide to the Security class.
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 )
{
throw new Exception("Unable to load the JSSE SSL stream handler." +
"Check classpath." + cfe.toString());
}
}
About applets
Https-based communication in the applet seems to be a natural extension of the above content. In fact, https communication in the applet is easier to implement in most cases. In versions 4.0 or later of Netscape Navigator and Internet Explorer, their respective virtual machines both use the HTTPS protocol by default. Therefore, if you want to create an HTTPS connection in the applet code URL
You can set the protocol name to "HTTPS.
URL url = new URL("https://[your server]");
If the client browser runs Sun's Java 2 plug-in, you may encounter some other restrictions when using HTTPS. For more information about using HTTPS in the Java 2 plug-in, visit the sun website (see the documents at the end of this Article ).
Conclusion
Using HTTPS in applications is a fast and efficient way to obtain sufficient security in communication. Unfortunately, it is not supported by the standard Java specification for legal rather than technical reasons. In any case, with the emergence of JSSE and Microsoftcom.ms.net.wininet
The use of packages requires a few lines of code on most platforms to implement secure communication.
About the author Matt towers, called ebozo, recently left his position in Visio. After that, I joined predictpoint.com, an Internet company in Seattle, Washington, where I worked on full-time Java development. |
Materials
- The cross-platform implementation code described in this article is called
HttpsMessage
Class.HttpsMessage
YesHttpMessage
Class subclass.HttpMessage
The class is written by Jason Hunter, that isJava Servlet ProgrammingThe author of (O 'Reilly & Associates). In the second edition of his upcoming book, you can findHttpsMessage
Class. To inherit this class, you must download and installcom.oreily.servlets
Package. This package and related sub-source code can be found on Hunter's site:
Http://www.servlets.com
- You can also download
HttpsMessage
Class source code compressed file:
Httpsmessage.zip
- The following are some web addresses used to test HTTPS communication:
- Https://www.verisign.com/
- Https://happiness.dhs.org/
- Https://www.microsoft.com
- Https://www.sun.com
- Https://www.ftc.gov
- For more information about JSSE, downloadable bits, and installation instructions, refer to Sun's website:
Http://java.sun.com/products/jsse.
- Descriptions of how to use some JSSE services, including the methods mentioned above, can be found in "secure networking in Java" written by Jonathan Knudsen on the o'reilly Website:
Http://java.oreilly.com/bite-size/java_1099.html
- More about
WininetStreamHandlerFactory
Class information can be found at http://www.microsoft.com/java/sdk/in Microsoft's jsdk documentation /. In addition, Microsoft Knowledge Base also published "PRB: allowing the URL class to access HTTPS in Applications ":
Http://support.microsoft.com/support/kb/articles/Q191/1/20.ASP
- For more information about using HTTPS in the Java 2 plug-in, refer to "How HTTPS works in Java Plug-in" on the sun site:
Http://java.sun.com/products/plugin/1.2/docs/https.html