1
votes

I'm trying to create my own HTTPS server and I have two code snippets:

The first:

private SSLContext createSSLContext() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException, NoSuchProviderException {
    KeyStore keyStore = KeyStore.getInstance("JKS");
    keyStore.load(new FileInputStream("c:\\tmp\\clientkeystore.jks"), "123456".toCharArray());

    // Create key manager
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
    keyManagerFactory.init(keyStore, "123456".toCharArray());
    KeyManager[] km = keyManagerFactory.getKeyManagers();

    // Create trust manager
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
    trustManagerFactory.init(keyStore);
    TrustManager[] tm = trustManagerFactory.getTrustManagers();

    // Initialize SSLContext
    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(km, tm, null);

    return sslContext;
}

The second:

private SSLContext createSSLContext2() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException, NoSuchProviderException {
    String path = "c:/tmp/example.crt2";
    byte[] certbytes = Files.readAllBytes(Paths.get(path));

    ByteArrayInputStream derInputStream = new ByteArrayInputStream(certbytes);
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(derInputStream);
    String alias = cert.getSubjectX500Principal().getName();

    KeyStore trustStore = KeyStore.getInstance("JKS");
    trustStore.load(null, "".toCharArray());
    trustStore.setCertificateEntry(alias, cert);
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(trustStore, null);
    KeyManager[] keyManagers = kmf.getKeyManagers();

    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(trustStore);
    TrustManager[] trustManagers = tmf.getTrustManagers();

    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(keyManagers, trustManagers, null);
    return sslContext;
}

Everything works great with the first snippet, however, I would like to get more - I created self-signed SSL certificate for my local domain and saved it in the external file. When I try to use that certificate (example.crt2), I had the following exception:

javax.net.ssl.SSLHandshakeException: no cipher suites in common at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:292)

and the full output of curl is:

$ curl -k -vvv https://example.org:443 * Rebuilt URL to: https://example.org:443/ * timeout on name lookup is not supported * Trying 127.0.0.1... * Connected to example.org (127.0.0.1) port 443 (#0) * ALPN, offering http/1.1 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * successfully set certificate verify locations: * CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt CApath: none * TLSv1.2 (OUT), TLS header, Certificate Status (22): * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS header, Unknown (21): * TLSv1.2 (IN), TLS alert, Server hello (2): * error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure * Closing connection 0 curl: (35) error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

The certificate in clientkeystore.jks was generated by the following command line:

keytool -genkey ...

The certificate for the second snippet was generated via openssl:

$ openssl version -a
OpenSSL 1.0.2e 3 Dec 2015
built on: reproducible build, date unspecified
platform: mingw64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,2,long) idea(int) blowfish(idx)
compiler: gcc -I. -I.. -I../include -I/mingw64/include -D_WINDLL -DOPENSSL_PIC -DZLIB_SHARED -DZLIB -DOPENSSL_THREADS -D_MT -DDSO_WIN32 -DL_ENDIAN -O3 -Wall -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
OPENSSLDIR: "/mingw64/ssl"

What do I make wrong? Please, help!

1
no shared cipher could indicate a problem with an EC key and use of domain parameters instead of a named curve. Also see Elliptic Curve Cryptography | Named Curves on the OpenSSL wiki. You need to provide the certificate that's causing problems to know for sure if this is the problem.jww

1 Answers

2
votes

In the second case there is no private key, only a certificate. You need to initialize the KeyManager with a TrustStore that contains a private-key entry.

What you're doing doesn't make sense anyway. You can't use the same file as both a KeyStore and a truststore. It doesn't make any sense.