Java Tip 96 : Java 클라이언트 코드에서 HTTPS 사용

Java 클라이언트와 HTTPS (HyperText Transfer Protocol Secure) 서버 사이에 보안 통신을 구현하려고 시도한 적이 있다면 표준 java.net.URL클래스가 HTTPS 프로토콜을 지원하지 않는다는 사실을 발견했을 것입니다 . 이 방정식의 서버 측 구현은 매우 간단합니다. 오늘날 사용 가능한 거의 모든 웹 서버는 HTTPS를 사용하여 데이터를 요청하는 메커니즘을 제공합니다. 웹 서버를 설정하면 모든 브라우저가 URL에 대한 프로토콜로 HTTPS를 지정하기 만하면 서버에서 보안 정보를 요청할 수 있습니다. 아직 HTTPS 서버를 설정하지 않은 경우 인터넷의 거의 모든 HTTPS 웹 페이지에서 클라이언트 코드를 테스트 할 수 있습니다. 리소스 섹션에는 해당 용도로 사용할 수있는 후보 목록이 포함되어 있습니다.

그러나 클라이언트 관점에서 친숙한 HTTP 끝에있는 S의 단순성은 속이는 것입니다. 브라우저는 실제로 귀하가 요청한 정보를 아무도 조작하거나 모니터링하지 않았는지 확인하기 위해 상당한 양의이면 작업을 수행하고 있습니다. 결과적으로 HTTPS 암호화를 수행하는 알고리즘은 RSA Security에서 특허를 받았습니다 (적어도 몇 개월 이상). 이 알고리즘의 사용은 브라우저 제조업체에 의해 허가되었지만 Sun Microsystems에서 표준 Java URL클래스 구현에 포함되도록 허가하지 않았습니다 . 결과적으로 URLHTTPS를 프로토콜로 지정하는 문자열 로 객체 를 생성하려고하면 a MalformedURLException가 발생합니다.

다행히도 이러한 제약을 수용하기 위해 Java 사양은 URL클래스에 대한 대체 스트림 처리기를 선택할 수있는 기능을 제공합니다 . 그러나이를 구현하는 데 필요한 기술은 사용하는 가상 머신 (VM)에 따라 다릅니다. Microsoft의 JDK 1.1 호환 VM 인 JView의 경우 Microsoft는 알고리즘에 라이선스를 부여하고 wininet패키지의 일부로 HTTPS 스트림 처리기를 제공했습니다 . 반면 Sun은 최근 JDK 1.2 호환 VM 용 JSSE (Java Secure Sockets Extension)를 출시했으며, 여기에서 Sun은 HTTPS 스트림 처리기를 라이센스하고 제공했습니다. 이 기사에서는 JSSE와 Microsoft의 wininet패키지를 사용하여 HTTPS 지원 스트림 처리기의 사용을 구현하는 방법을 보여줍니다 .

JDK 1.2 호환 가상 머신

JDK 1.2 호환 VM을 사용하는 기술은 주로 JSSE (Java Secure Sockets Extension) 1.0.1에 의존합니다. 이 기술이 작동하기 전에 JSSE를 설치하고 해당 클라이언트 VM의 클래스 경로에 추가해야합니다.

JSSE를 설치 한 후 시스템 속성을 설정하고 새 보안 공급자를 Security클래스 개체에 추가해야 합니다. 이 두 가지 작업을 수행하는 다양한 방법이 있지만이 기사에서는 프로그래밍 방식의 방법이 표시됩니다.

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

앞의 두 메서드 호출을 수행 한 후에 MalformedURLException는 다음 코드를 호출하여 더 이상 throw되지 않습니다.

 URL url = new URL ( "// [사용자 서버]"); 

표준 SSL 포트 443에 연결하는 경우 URL 문자열에 포트 번호를 추가 할 수 있습니다. 그러나 웹 서버가 SSL 트래픽에 비표준 포트를 사용하는 경우 다음과 같이 URL 문자열에 포트 번호를 추가해야합니다.

 URL url = new URL ( "// [사용자 서버] : 7002"); 

이 기술의 한 가지주의 사항은 서명되지 않았거나 잘못된 SSL 인증서가있는 서버를 참조하는 URL과 관련이 있습니다. 이 경우 URL의 연결 개체에서 입력 또는 출력 스트림을 검색하려고하면 SSLException"신뢰할 수없는 서버 인증서 체인"이라는 메시지가 표시됩니다. 서버에 유효한 서명 된 인증서가있는 경우 예외가 발생하지 않습니다.

URL url = new URL ( "// [사용자 서버]"); URLConnection con = URL.openConnection (); // 서버 인증서가 유효하지 않은 경우 여기에서 SSLException 발생 con.getInputStream ();

이 문제에 대한 확실한 해결책은 서버에 대한 서명 된 인증서를 얻는 것입니다. 그러나 다음 URL 중 하나도 솔루션을 제공 할 수 있습니다. "Java Secure Socket Extension 1.0.2 변경 사항"(Sun Microsystems) 또는 Sun의 Java Developer Connection 포럼.

Microsoft JView

부분적으로는 Windows 플랫폼에서 사용하기위한 Java 라이센스에 대한 Microsoft와 Sun 간의 지속적인 분쟁으로 인해 Microsoft JView VM은 현재 JDK 1.1 과만 호환됩니다. 따라서 위에서 설명한 기술은 JView에서 실행되는 클라이언트에는 작동하지 않습니다. JSSE에는 최소한 1.2.2 호환 VM이 필요하기 때문입니다. 그러나 편리하게도 Microsoft는 com.ms.net.wininet패키지의 일부로 HTTPS 사용 스트림 처리기를 제공 합니다.

URL클래스 에서 단일 정적 메소드를 호출하여 JView 환경에서 스트림 핸들러를 설정할 수 있습니다 .

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

이전 메서드 호출을 수행 한 후

MalformedURLException

다음 코드를 호출하여 더 이상 던지지 않습니다.

 URL url = new URL ( "// [사용자 서버]"); 

이 기술과 관련된 두 가지주의 사항이 있습니다. 첫째, JDK 문서에 따르면 setURLStreamHandlerFactory메서드는 주어진 VM에서 최대 한 번 호출 될 수 있습니다. 이후에 해당 메서드를 호출하려고하면 Error. 둘째, 1.2 VM 솔루션의 경우와 마찬가지로 서명되지 않았거나 잘못된 SSL 인증서가있는 서버를 참조하는 URL을 사용할 때주의해야합니다. 앞의 경우와 마찬가지로 URL의 연결 개체에서 입력 또는 출력 스트림을 검색하려고하면 문제가 발생합니다. 그러나을 throw하는 대신 SSLExceptionMicrosoft 스트림 처리기는 표준 IOException.

URL url = new URL ( "// [사용자 서버]"); URLConnection con = url.openConnection (); // 서버 인증서가 유효하지 않은 경우 여기에서 IOException 발생 con.getInputStream ();

다시 말하지만,이 문제에 대한 확실한 해결책은 서명 된 유효한 인증서가있는 서버와 만 HTTPS 통신을 시도하는 것입니다. 그러나 JView는 다른 옵션을 제공합니다. URL의 연결 개체에서 입력 또는 출력 스트림을 검색하기 직전에 연결 개체를 호출 할 수 있습니다 setAllowUserInteraction(true). 그러면 JView는 서버의 인증서가 유효하지 않다는 경고 메시지를 사용자에게 표시하지만 계속 진행할 수있는 옵션을 제공합니다. 그러나 이러한 메시지는 데스크톱 응용 프로그램에 적합 할 수 있지만 디버깅 목적 이외의 목적으로 서버에 대화 상자가 나타나는 것은 허용되지 않을 수 있습니다.

참고 : setAllowUserInteraction()JDK 1.2 호환 VM에서 메서드를 호출 할 수도 있습니다 . 그러나 Sun의 1.2 VM (이 코드가 테스트 된)을 사용하는 경우 해당 속성이 true로 설정되어 있어도 대화 상자가 표시되지 않습니다.

URL url = new URL ( "// [사용자 서버]"); URLConnection con = url.openConnection (); // 신뢰할 수없는 서버에 연결할 때 // VM이 대화 상자를 표시하도록합니다. con.setAllowUserInteraction (true); con.getInputStream ();

com.ms.net.wininet패키지 설치 및 Windows NT 4.0, Windows 2000 및 Windows 9x의 시스템에서 기본적으로 시스템 클래스 경로에 배치 될 것으로 보인다. 또한 Microsoft JDK 문서에 따르면 WinInetStreamHandlerFactory"... 애플릿을 실행할 때 기본적으로 설치되는 동일한 처리기"입니다.

플랫폼 독립성

내가 설명한 두 기술 모두 Java 클라이언트가 실행될 수있는 대부분의 플랫폼을 다루지 만 Java 클라이언트는 JDK 1.1 및 JDK 1.2 호환 VM 모두에서 실행되어야 할 수 있습니다. "한 번 쓰고 어디에서나 실행"기억하십니까? 결과적으로 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")) {try {Class clsFactory = Class.forName ( "com.ms.net.wininet.WininetStreamHandlerFactory"); if (null! = clsFactory) URL.setURLStreamHandlerFactory ((URLStreamHandlerFactory) clsFactory.newInstance ()); } catch (ClassNotFoundException cfe) {throw new Exception ( "Microsoft SSL을로드 할 수 없습니다."+ "스트림 처리기. 클래스 경로를 확인하십시오."+ cfe.toString ());} // 스트림 핸들러 팩토리가 // 이미 성공적으로 설정된 경우 // 플래그가 설정되어 있는지 확인하고 오류를 잡아냅니다. catch (Error err) {m_bStreamHandlerSet = true;}} // 일반 Java 환경에있는 경우 // JSSE 핸들러를 사용해보십시오. // 참고 : JSSE에는 1.2 이상이 필요합니다. else if (1.2 <= dVersion.doubleValue ()) {System.setProperty ( "java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol "); try {// 사용 가능한 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) {throw new Exception ( "JSSE SSL 스트림 핸들러를로드 할 수 없습니다."+ "클래스 경로를 확인하십시오."+ cfe.toString ()); }}

애플릿은 어떻습니까?

애플릿 내에서 HTTPS 기반 통신을 수행하는 것은 위에서 설명한 시나리오의 자연스러운 확장처럼 보입니다. 실제로는 대부분의 경우 훨씬 더 쉽습니다. 4.0 이상 버전의 Netscape Navigator 및 Internet Explorer에서 HTTPS는 해당 VM에 대해 기본적으로 활성화됩니다. 따라서 애플릿 코드 내에서 HTTPS 연결을 생성하려면 URL클래스 의 인스턴스를 생성 할 때 HTTPS를 프로토콜로 지정하면 됩니다.

 URL url = new URL ( "// [사용자 서버]"); 

클라이언트 브라우저가 Sun의 Java 2 플러그인을 실행하는 경우 HTTPS를 사용할 수있는 방법에 대한 추가 제한이 있습니다. Java 2 플러그인과 함께 HTTPS를 사용하는 방법에 대한 자세한 내용은 Sun 웹 사이트 (참고 자료 참조)에서 확인할 수 있습니다.

결론

애플리케이션간에 HTTPS 프로토콜을 사용하면 통신에서 합리적인 수준의 보안을 확보 할 수있는 빠르고 효과적인 방법이 될 수 있습니다. 불행히도 표준 Java 사양의 일부로 지원되지 않는 이유는 기술적 인 것보다 합법적 인 것으로 보입니다. 그러나 JSSE의 출현과 Microsoft의 com.ms.net.winint패키지 사용 으로 코드 몇 줄만으로 대부분의 플랫폼에서 안전한 통신이 가능해졌습니다.

자칭 eBozo 인 Matt Towers는 최근 Visio에서 개발 직책을 떠났습니다. 이후 워싱턴 주 시애틀에있는 인터넷 스타트 업인 PredictPoint.com에 합류하여 풀 타임 Java 개발자로 일하고 있습니다.

이 주제에 대해 더 알아보기

  • 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

이 스토리 "Java Tip 96 : Java 클라이언트 코드에서 HTTPS 사용"은 원래 JavaWorld에서 게시했습니다.