[ไม่รองรับการเข้ารหัส] [Java SSLSocket]

Aug 27 2020

ฉันกำลังพยายามเชื่อมต่อเซิร์ฟเวอร์ผ่าน SSLSocket โดยใช้โปรโตคอล TLSv1.2 เซิร์ฟเวอร์รองรับเฉพาะการเข้ารหัสต่อไปนี้

  • ECDHE-ECDSA-AES128-GCM-SHA256
  • ECDHE-RSA-AES128-GCM-SHA256
  • ECDHE-ECDSA-AES128-SHA256

เมื่อฉันพยายามตั้งค่าชุดการเข้ารหัสที่เปิดใช้งานฉันกำลังเผชิญกับข้อยกเว้นดังต่อไปนี้:

java.lang.IllegalArgumentException: Unsupported ciphersuite ECDHE-ECDSA-AES128-GCM-SHA256
at sun.security.ssl.CipherSuite.valueOf(Unknown Source) ~[?:1.8.0_74]
at sun.security.ssl.CipherSuiteList.<init>(Unknown Source) ~[?:1.8.0_74]
at sun.security.ssl.SSLSocketImpl.setEnabledCipherSuites(Unknown Source) ~[?:1.8.0_74]

ฉันได้พยายามแทนที่ Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 จาก URL ต่อไปนี้บน C: \ Program Files \ Java \ jdk1.8.0_92 \ jre \ lib \ security แต่ยังไม่สามารถเชื่อมต่อเซิร์ฟเวอร์ได้

URL: https://www.oracle.com/java/technologies/javase-jce8-downloads.html

ฉันใช้รหัสต่อไปนี้เพื่อสร้าง SSLSocket:

protected void openSocket() throws IOException {
    LGR.info("Opening SSL socket to " + addr + ":" + port);
    String[] TLS_SUPPORTED_VERSIONS = new String[] { "TLSv1.2" };
    String[] CIPHER_SUITES = new String[] { "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-SHA256" };
    try {
        SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(addr, port);
        socket.setEnabledProtocols(TLS_SUPPORTED_VERSIONS);
        socket.setEnabledCipherSuites(CIPHER_SUITES);
        
    } catch (Exception ex) {
        LGR.error("##Exception##", ex);
    } catch (Throwable ex) {
        LGR.error("##Throwable##", ex);
    }
}

คำตอบ

1 PeterWalser Aug 27 2020 at 16:20

คุณสามารถแสดงรายการชุดการเข้ารหัสที่รองรับโดยใช้:

SSLSocketFactory socketFactory = SSLContext.getDefault().getSocketFactory();
for (String cipherSuite : socketFactory.getSupportedCipherSuites()) {
    System.out.println(cipherSuite);
}

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256รายการต่อไปนี้ตรงกับชุดที่ต้องการของคุณ:

คุณไม่จำเป็นต้องใช้ไฟล์นโยบายการบังคับใช้ JCE Unlimited Strength อีกต่อไป:

  • ใน Java 8 u151 / u152 ไฟล์นโยบายรวมอยู่ในการแจกจ่าย Java มาตรฐาน แต่จำเป็นต้องเปิดใช้งานอย่างชัดเจน: Security.setProperty("crypto.policy", "unlimited");
  • ตั้งแต่ Java 8 u161 + (และในเวอร์ชัน Java ที่กำลังจะมาถึงทั้งหมด) ไฟล์นโยบายเหล่านี้จะรวมอยู่ด้วยและเปิดใช้นโยบายการเข้ารหัสลับแบบไม่ จำกัด โดยค่าเริ่มต้น

คุณสามารถตรวจสอบได้ดังนี้Cipher.getMaxAllowedKeyLength("AES")ควรกลับมาInteger.MAX_VALUEเมื่อเปิดใช้งาน unlimited strengh