ในที่สุดก็จัดการเพื่อแก้ไขปัญหาทั้งหมดดังนั้นฉันจะตอบคำถามของฉันเอง นี่คือการตั้งค่า / ไฟล์ที่ฉันเคยจัดการเพื่อแก้ไขปัญหาเฉพาะของฉัน
ที่เก็บคีย์ของไคลเอ็นต์คือไฟล์รูปแบบ PKCS # 12ที่มี
- ใบรับรองสาธารณะของลูกค้า(ในอินสแตนซ์นี้ลงนามโดย CA ที่ลงนามด้วยตนเอง)
- คีย์ส่วนตัวของลูกค้า
เพื่อสร้างมันฉันใช้pkcs12
คำสั่งของ OpenSSL เช่น;
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "Whatever"
เคล็ดลับ:ตรวจสอบให้แน่ใจว่าคุณได้รับ OpenSSL ล่าสุดไม่ใช่เวอร์ชัน 0.9.8h เนื่องจากดูเหมือนว่าจะมีปัญหาจากบั๊กซึ่งไม่อนุญาตให้คุณสร้างไฟล์ PKCS # 12 อย่างถูกต้อง
ไฟล์ PKCS # 12 นี้จะถูกใช้โดยไคลเอนต์ Java เพื่อแสดงใบรับรองไคลเอ็นต์ไปยังเซิร์ฟเวอร์เมื่อเซิร์ฟเวอร์ได้ร้องขอให้ไคลเอนต์รับรองความถูกต้องอย่างชัดเจน ดูบทความ Wikipedia บน TLSสำหรับภาพรวมของวิธีการใช้งานโปรโตคอลสำหรับการตรวจสอบใบรับรองลูกค้าจริง (อธิบายด้วยว่าทำไมเราต้องใช้รหัสส่วนตัวของลูกค้าที่นี่)
truststore ของลูกค้าเป็นตรงไปตรงมาในรูปแบบจางกึนซอกไฟล์ที่มีรากหรือใบรับรอง CA กลาง ใบรับรอง CA เหล่านี้จะกำหนดปลายทางที่คุณจะได้รับอนุญาตให้สื่อสารด้วยในกรณีนี้จะช่วยให้ลูกค้าของคุณเชื่อมต่อกับเซิร์ฟเวอร์ใดก็ตามที่แสดงใบรับรองที่ลงชื่อโดย CA แห่งใดแห่งหนึ่งของ truststore
เพื่อสร้างมันคุณสามารถใช้ Java keytool มาตรฐานตัวอย่างเช่น
keytool -genkey -dname "cn=CLIENT" -alias truststorekey -keyalg RSA -keystore ./client-truststore.jks -keypass whatever -storepass whatever
keytool -import -keystore ./client-truststore.jks -file myca.crt -alias myca
ใช้ truststore นี้ลูกค้าของคุณจะพยายามที่จะทำจับมือ SSL ที่สมบูรณ์แบบด้วยเซิร์ฟเวอร์ทั้งหมดที่นำเสนอใบรับรองที่ลงนามโดย CA myca.crt
ที่ระบุโดย
ไฟล์ด้านบนใช้สำหรับลูกค้าเท่านั้น เมื่อคุณต้องการตั้งค่าเซิร์ฟเวอร์เช่นกันเซิร์ฟเวอร์ต้องใช้ไฟล์คีย์และ truststore ของตัวเอง การเดินผ่านที่ยอดเยี่ยมสำหรับการตั้งค่าตัวอย่างการทำงานอย่างสมบูรณ์สำหรับทั้งไคลเอนต์ Java และเซิร์ฟเวอร์ (ใช้ Tomcat) สามารถพบได้บนเว็บไซต์นี้
ประเด็นปัญหา / ข้อสังเกต / เคล็ดลับ
- การพิสูจน์ตัวตนใบรับรองไคลเอ็นต์สามารถบังคับใช้โดยเซิร์ฟเวอร์เท่านั้น
- ( สำคัญ! ) เมื่อเซิร์ฟเวอร์ร้องขอใบรับรองไคลเอ็นต์ (ซึ่งเป็นส่วนหนึ่งของการจับมือ TLS) ก็จะแสดงรายการ CA ที่เชื่อถือได้ซึ่งเป็นส่วนหนึ่งของคำขอใบรับรอง เมื่อใบรับรองลูกค้าที่คุณต้องการนำเสนอสำหรับการตรวจสอบสิทธิ์ไม่ได้ลงนามโดยหนึ่งใน CA เหล่านี้มันจะไม่ถูกนำเสนอเลย (ในความคิดของฉันนี่เป็นพฤติกรรมแปลก ๆ แต่ฉันแน่ใจว่ามีเหตุผล) นี่เป็นสาเหตุหลักของปัญหาของฉันเนื่องจากบุคคลอื่นไม่ได้กำหนดค่าเซิร์ฟเวอร์ของตนให้ยอมรับใบรับรองไคลเอ็นต์ที่ลงชื่อด้วยตนเองของฉันและเราคิดว่าปัญหานี้สิ้นสุดแล้วที่ฉันไม่ได้ให้ใบรับรองไคลเอ็นต์ในคำขออย่างถูกต้อง
- รับ Wireshark มีการวิเคราะห์แพ็คเก็ต SSL / HTTPS ที่ยอดเยี่ยมและจะช่วยในการแก้ไขข้อบกพร่องและค้นหาปัญหาได้อย่างมาก มันคล้ายกับ
-Djavax.net.debug=ssl
แต่มีโครงสร้างมากขึ้นและ (ตีความ) ง่ายต่อการตีความหากคุณรู้สึกไม่สะดวกใจกับ Java debug output
เป็นไปได้อย่างสมบูรณ์ที่จะใช้ Apache httpclient library หากคุณต้องการใช้ httpclient เพียงแค่แทนที่ URL ปลายทางด้วย HTTPS ที่เทียบเท่าและเพิ่มอาร์กิวเมนต์ JVM ต่อไปนี้ (ซึ่งเหมือนกันสำหรับไคลเอนต์อื่น ๆ โดยไม่คำนึงถึงไลบรารีที่คุณต้องการใช้ในการส่ง / รับข้อมูลผ่าน HTTP / HTTPS) :
-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.keyStore=client.p12
-Djavax.net.ssl.keyStorePassword=whatever
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.trustStore=client-truststore.jks
-Djavax.net.ssl.trustStorePassword=whatever