טיפ 96 של Java: השתמש ב- HTTPS בקוד לקוח Java שלך

אם ניסית אי פעם ליישם תקשורת מאובטחת בין לקוח Java לשרת HTTPS (HyperText Transfer Protocol Secure), כנראה שגילית java.net.URLשהמחלקה הסטנדרטית אינה תומכת בפרוטוקול HTTPS. היישום בצד השרת של משוואה זו פשוט למדי. כמעט כל שרת אינטרנט הזמין כיום מספק מנגנון לבקשת נתונים, באמצעות HTTPS. לאחר שהגדרת את שרת האינטרנט שלך, כל דפדפן יכול לבקש מידע מאובטח מהשרת שלך פשוט על ידי ציון HTTPS כפרוטוקול לכתובת האתר. אם טרם הוגדר שרת HTTPS, תוכל לבדוק את קוד הלקוח שלך כמעט בכל דף אינטרנט של HTTPS באינטרנט. סעיף משאבים מכיל רשימה קצרה של מועמדים בהם תוכלו להשתמש למטרה זו.

מנקודת מבט הלקוח, לעומת זאת, הפשטות של ה- S בסוף ה- HTTP המוכר היא רמאות. הדפדפן למעשה מבצע כמות נכבדה של עבודה מאחורי הקלעים כדי להבטיח שאיש לא התעסק עם המידע שביקשתם או פיקח עליו. כפי שמתברר, האלגוריתם לבצע את ההצפנה עבור HTTPS הוא פטנט על ידי RSA Security (לפחות עוד כמה חודשים). השימוש באלגוריתם זה הוענק ברישיון על ידי יצרני הדפדפנים אך לא היה מורשה על ידי Sun Microsystems להיכלל URLביישום מחלקת Java הרגיל . כתוצאה מכך, אם תנסה לבנות URLאובייקט עם מחרוזת המציינת את HTTPS כפרוטוקול, MalformedURLExceptionייזרק.

למרבה המזל, כדי להתאים את האילוץ הזה, מפרט Java מספק את היכולת לבחור מטפל זרם חלופי URLלכיתה. עם זאת, הטכניקה הנדרשת ליישום שונה, בהתאם למכונה הווירטואלית (VM) בה אתה משתמש. עבור ה- VM התואם JDK 1.1 של מיקרוסופט, JView, מיקרוסופט רישאה את האלגוריתם וסיפקה מטפל בזרם HTTPS כחלק wininetמהחבילה שלו . לעומת זאת, סאן פרסמה לאחרונה את הרחבה Java Secure Sockets (JSSE) עבור מחשבי VM תואמי JDK 1.2, בה סאן גם רישתה וסיפקה מטפל בזרמי HTTPS. מאמר זה ידגים כיצד ליישם את השימוש במטפל בזרם תומך HTTPS, באמצעות JSSE wininetוחבילה של מיקרוסופט .

מכונות וירטואליות תואמות JDK 1.2

הטכניקה לשימוש ב- VMs תואמי JDK 1.2 מסתמכת בעיקר על הרחבת Java Secure Sockets (JSSE) 1.0.1. לפני שטכניקה זו תעבוד, עליך להתקין את JSSE ולהוסיף אותה לנתיב המחלקה של ה- VM הלקוח המדובר.

לאחר התקנת ה- JSSE, עליך להגדיר מאפיין מערכת ולהוסיף ספק אבטחה חדש Securityלאובייקט הכיתה. ישנן מגוון דרכים לעשות את שני הדברים הללו, אך לצורך מאמר זה מוצגת השיטה הפרוגרמטית:

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

לאחר ביצוע שתי קריאות השיטה הקודמות, MalformedURLExceptionהשיחה לא תושלך עוד על ידי קריאת הקוד הבא:

 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 ();

הפתרון הברור לבעיה זו הוא קבלת אישורים חתומים לשרת שלך. עם זאת, אחת מכתובות האתר הבאות עשויה לספק פיתרון: "שינויים ב- Java Secure Socket Extension 1.0.2" (Sun Microsystems) או פורום חיבור המפתחים של Java.

מיקרוסופט JView

בין השאר בשל המחלוקת המתמשכת בין מיקרוסופט לסאן על רישוי ג'אווה לשימוש בפלטפורמות Windows, ה- Microsoft JView VM תואם כרגע רק ל- JDK 1.1. לכן, הטכניקה שתוארה לעיל לא תפעל עבור לקוחות הפועלים ב- JView, מכיוון ש- JSSE דורש לפחות VM תואם 1.2.2. באופן נוח, עם זאת, מיקרוסופט מספקת מטפל בזרם תומך HTTPS כחלק com.ms.net.wininetמהחבילה.

אתה יכול להגדיר את מטפל הזרמים בסביבת JView על ידי קריאה לשיטה סטטית אחת URLבכיתה:

 URL.setURLStreamHandlerFactory (com.ms.net.wininet.WininetStreamHandlerFactory חדש ()); 

לאחר ביצוע שיחת השיטה הקודמת,

MalformedURLException

לא ייזרק עוד על ידי קריאת הקוד הבא:

 URL url = URL חדש ("// [השרת שלך]"); 

ישנם שני אזהרות הקשורות לטכניקה זו. ראשית, על פי תיעוד JDK, setURLStreamHandlerFactoryניתן לקרוא לשיטה לכל היותר פעם ב- VM נתון. ניסיונות הבאים להתקשר לשיטה זו יזרקו Error. שנית, כמו שקורה בפתרון 1.2 VM, עליכם להיות זהירים בעת שימוש בכתובת URL המתייחסת לשרת עם אישור SSL לא חתום או לא חוקי. כמו במקרה הקודם, בעיות מתרחשות כשמנסים לאחזר את זרם הקלט או הפלט מאובייקט החיבור של כתובת האתר. עם זאת, במקום לזרוק SSLException, מטפל הזרמים של מיקרוסופט זורק תקן IOException.

URL url = URL חדש ("// [השרת שלך]"); URLConnection con = url.openConnection (); // IOException נזרק לכאן אם אישור השרת אינו חוקי con.getInputStream ();

שוב, הפיתרון הברור לבעיה זו הוא ניסיון לתקשר HTTPS רק עם שרתים בעלי תעודה חתומה ותקפה. עם זאת, JView מציע אפשרות אחרת. מיד לפני אחזור קלט או זרם הפלט מאובייקט החיבור של כתובת האתר, אתה יכול להתקשר setAllowUserInteraction(true)לאובייקט החיבור. זה יגרום ל- JView להציג הודעה המזהירה את המשתמש כי אישורי השרת אינם תקפים, אך נותנת לו אפשרות להמשיך בכל מקרה. עם זאת, זכור כי הודעות מסוג זה עשויות להיות סבירות ליישום שולחן עבודה, אך ככל הנראה תיבות דו-שיח מופיעות בשרת שלך למטרות ניפוי באגים ככל הנראה אינו מקובל.

הערה: ניתן להתקשר setAllowUserInteraction()לשיטה גם במחשבי VM תואמי JDK 1.2. עם זאת, בשימוש ב- 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, ומערכות 9x Windows. כמו כן, על פי תיעוד Microsoft JDK, WinInetStreamHandlerFactoryהוא "... אותו מטפל המותקן כברירת מחדל בעת הפעלת יישומונים."

עצמאות פלטפורמה

למרות ששתי הטכניקות שתיארתי מכסות את רוב הפלטפורמות בהן לקוח ה- Java שלך עשוי לפעול, ייתכן שלקוח ה- Java שלך יצטרך לפעול גם ב- VM-תואם JDK 1.1 וגם ב- JDK 1.2. "כתוב פעם אחת, רץ לכל מקום," זוכר? כפי שמתברר, שילוב של שתי טכניקות אלה כך שהמטפל המתאים נטען בהתאם ל- VM, הוא די פשוט. הקוד הבא מדגים דרך לעשות זאת:

מחרוזת strVendor = System.getProperty ("java.vendor"); מחרוזת strVersion = System.getProperty ("java.version"); // מניח מחרוזת גרסת מערכת של הטופס: // [גדול]. [קטין]. [שחרור] (למשל 1.2.2) כפול dVersion = כפול חדש (strVersion.substring (0, 3)); // אם אנו פועלים בסביבת MS, השתמש במטפל הזרם של MS. אם (-1 <strVendor.indexOf ("Microsoft")) {נסה {Class clsFactory = Class.forName ("com.ms.net.wininet.WininetStreamHandlerFactory"); אם (null! = clsFactory) URL.setURLStreamHandlerFactory ((URLStreamHandlerFactory) clsFactory.newInstance ()); } לתפוס (ClassNotFoundException cfe) {לזרוק חריג חדש ("לא ניתן לטעון את מטפל הזרם של Microsoft SSL" + ". בדוק את מסלול הכניסה." + cfe.toString ());} // אם מפעל מטפלי הזרם // כבר הוגדר בהצלחה // ודא שהדגל שלנו מוגדר ואכל את תפיסת השגיאה (שגיאה שגיאה) {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 זמין, // והוא עדיין לא הוגדר //, הוסף אותו כמספק חדש למחלקת האבטחה. מחלקה clsFactory = Class.forName ("com.sun.net.ssl.internal.ssl.Provider"); if ((null! = clsFactory) && (null == Security.getProvider ("SunJSSE"))) Security.addProvider ((Provider) clsFactory.newInstance ());} לתפוס (ClassNotFoundException cfe) {throw Exception new ("לא ניתן לטעון את מטפל הזרם SSL של JSSE." + "בדוק את מסלול הכיתה." + 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 והשימוש com.ms.net.winintבחבילה של מיקרוסופט , תקשורת מאובטחת אפשרית מרוב הפלטפורמות עם מספר שורות קוד בלבד.

מאט טאוורס, eBozo המתואר בעצמו, עזב לאחרונה את תפקיד הפיתוח שלו אצל 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: השתמש ב- HTTPS בקוד לקוח Java שלך" פורסם במקור על ידי JavaWorld.