Issue
I want to create a simple TLS 1.3 server socket listener, which uses a self-signed certificate.
First I created a RSA public / private key pair:
openssl req -x509 -newkey rsa:2048 -sha256 -days 9125 -nodes -keyout test.key -out test.crt
I added the public and private key as a string in a simple Java program
public class TlsServer
{
private static final String TEST_CRT = "-----BEGIN CERTIFICATE-----\n"
// ...
+ "-----END CERTIFICATE-----";
private static final String TEST_KEY
= "-----BEGIN PRIVATE KEY-----\n"
// ...
+ "-----END PRIVATE KEY-----";
private static final int PORT = 32333;
private static final String TLS_PROTOCOL = "TLSv1.3";
private static final String[] CIPHER_SUITES = new String[]
{
"TLS_AES_128_GCM_SHA256",
"TLS_AES_256_GCM_SHA384"
};
public static void main(String[] args) throws Exception
{
new TlsServer().start();
}
private void start() throws Exception
{
//System.setProperty("javax.net.debug", "all");
SSLContext ctx = SSLContext.getInstance(TLS_PROTOCOL);
// Init Key Store.
char[] password = "changeit".toCharArray();
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, password);
Certificate cert = convertCertificate(TEST_CRT);
ks.setCertificateEntry("test_crt", cert);
Key pk = new SecretKeySpec(TEST_KEY.getBytes(StandardCharsets.ISO_8859_1), "RSA");
ks.setKeyEntry("test_key", pk, password, new Certificate[]
{
cert
});
// Init Key Manager Factory.
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password);
// Init Trust Manager Factory.
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLServerSocket serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(PORT);
serverSocket.setNeedClientAuth(false);
serverSocket.setEnabledProtocols(new String[]
{
TLS_PROTOCOL
});
serverSocket.setEnabledCipherSuites(CIPHER_SUITES);
System.out.printf("Server started on port %d%n", PORT);
while (true)
{
try (SSLSocket socket = (SSLSocket) serverSocket.accept())
{
System.out.println("Accept new connection: " + socket.getRemoteSocketAddress());
InputStream is = new BufferedInputStream(socket.getInputStream());
OutputStream os = new BufferedOutputStream(socket.getOutputStream());
byte[] data = new byte[2048];
int len = is.read(data);
if (len <= 0)
{
throw new IOException("No data received");
}
System.out.printf("Server received %d bytes: %s%n", len, new String(data, 0, len));
os.write(data, 0, len);
os.flush();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
private Certificate convertCertificate(String cert) throws CertificateException
{
InputStream in = new ByteArrayInputStream(cert.getBytes(StandardCharsets.ISO_8859_1));
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return certFactory.generateCertificate(in);
}
}
Java Version
openjdk version "11.0.11" 2021-04-20
OpenJDK Runtime Environment AdoptOpenJDK-11.0.11+9 (build 11.0.11+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK-11.0.11+9 (build 11.0.11+9, mixed mode)
The server starts and listens to the connection, but if I try to access the server with a client (e.g. curl, Chrome or a simple Java-Client), I get the following error:
Server started on port 32333
Accept new connection: /0:0:0:0:0:0:0:1:49966
javax.net.ssl.SSLHandshakeException: No available authentication scheme
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:336)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:283)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.onProduceCertificate(CertificateMessage.java:972)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.produce(CertificateMessage.java:961)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1234)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1170)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:852)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:829)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:920)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:292)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:107)
at TlsServer.start(TlsServer.java:143)
at TlsServer.main(TlsServer.java:95)
The debug output look like this:
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.010 CEST|ServerHello.java:577|Produced ServerHello handshake message (
"ServerHello": {
"server version" : "TLSv1.2",
"random" : "78 B9 53 93 89 F9 8F 8C 2B 03 33 72 5D 21 4D A5 DC 42 59 CE 54 24 CD 75 9F 26 15 09 FB 53 91 00",
"session id" : "EC 09 75 BD 7F 00 40 CB 9F DC F4 BA FD 03 57 82 6C D0 6E 4C 2D FD 79 AA 07 91 86 A8 1C A8 99 38",
"cipher suite" : "TLS_AES_128_GCM_SHA256(0x1301)",
"compression methods" : "00",
"extensions" : [
"supported_versions (43)": {
"selected version": [TLSv1.3]
},
"key_share (51)": {
"server_share": {
"named group": x25519
"key_exchange": {
0000: B3 C2 7D 1D 77 D1 CE 3F 1D C2 15 0A 3A 21 B5 3B ....w..?....:!.;
0010: ED D0 BB 79 D1 C0 88 46 98 71 DD 2D 62 40 E1 1E ...y...F.q.-b@..
}
},
}
]
}
)
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.010 CEST|SSLSocketOutputRecord.java:241|WRITE: TLS13 handshake, length = 122
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.011 CEST|SSLSocketOutputRecord.java:255|Raw write (
0000: 16 03 03 00 7A 02 00 00 76 03 03 78 B9 53 93 89 ....z...v..x.S..
0010: F9 8F 8C 2B 03 33 72 5D 21 4D A5 DC 42 59 CE 54 ...+.3r]!M..BY.T
0020: 24 CD 75 9F 26 15 09 FB 53 91 00 20 EC 09 75 BD $.u.&...S.. ..u.
0030: 7F 00 40 CB 9F DC F4 BA FD 03 57 82 6C D0 6E 4C [email protected]
0040: 2D FD 79 AA 07 91 86 A8 1C A8 99 38 13 01 00 00 -.y........8....
0050: 2E 00 2B 00 02 03 04 00 33 00 24 00 1D 00 20 B3 ..+.....3.$... .
0060: C2 7D 1D 77 D1 CE 3F 1D C2 15 0A 3A 21 B5 3B ED ...w..?....:!.;.
0070: D0 BB 79 D1 C0 88 46 98 71 DD 2D 62 40 E1 1E ..y...F.q.-b@..
)
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.017 CEST|SSLCipher.java:1840|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.018 CEST|SSLCipher.java:1994|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.018 CEST|SSLSocketOutputRecord.java:225|Raw write (
0000: 14 03 03 00 01 01 ......
)
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.019 CEST|ServerNameExtension.java:527|Ignore unavailable extension: server_name
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.019 CEST|SSLExtensions.java:260|Ignore, context unavailable extension: server_name
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.019 CEST|MaxFragExtension.java:469|Ignore unavailable max_fragment_length extension
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.019 CEST|SSLExtensions.java:260|Ignore, context unavailable extension: max_fragment_length
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.020 CEST|AlpnExtension.java:365|Ignore unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.020 CEST|SSLExtensions.java:260|Ignore, context unavailable extension: application_layer_protocol_negotiation
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.020 CEST|EncryptedExtensions.java:137|Produced EncryptedExtensions message (
"EncryptedExtensions": [
"supported_groups (10)": {
"versions": [x25519, secp256r1, secp384r1, secp521r1, x448, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
}
]
)
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.020 CEST|SSLSocketOutputRecord.java:241|WRITE: TLS13 handshake, length = 32
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.028 CEST|SSLCipher.java:2036|Plaintext before ENCRYPTION (
0000: 08 00 00 1C 00 1A 00 0A 00 16 00 14 00 1D 00 17 ................
0010: 00 18 00 19 00 1E 01 00 01 01 01 02 01 03 01 04 ................
0020: 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0030: 00 .
)
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.028 CEST|SSLSocketOutputRecord.java:255|Raw write (
0000: 17 03 03 00 41 7D 95 DC 2E 14 CB 2C B5 B3 D4 79 ....A......,...y
0010: 67 4C D6 01 7E 7C EE 31 58 A3 63 33 E1 30 0E 3C gL.....1X.c3.0.<
0020: FB 73 DD 85 57 95 36 B5 93 17 73 3A E6 2E 6C A9 .s..W.6...s:..l.
0030: A1 F0 49 15 93 28 39 A8 E3 ED D5 02 85 05 09 37 ..I..(9........7
0040: 28 3F B3 52 62 94 (?.Rb.
)
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.028 CEST|X509Authentication.java:295|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: ecdsa_secp256r1_sha256
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.029 CEST|X509Authentication.java:295|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: ecdsa_secp384r1_sha384
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.029 CEST|X509Authentication.java:295|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: ecdsa_secp521r1_sha512
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.029 CEST|X509Authentication.java:295|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pss_rsae_sha256
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.029 CEST|X509Authentication.java:295|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pss_rsae_sha384
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.029 CEST|X509Authentication.java:295|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pss_rsae_sha512
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.029 CEST|X509Authentication.java:295|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pss_pss_sha256
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.029 CEST|X509Authentication.java:295|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.029 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pss_pss_sha384
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.030 CEST|X509Authentication.java:295|No X.509 cert selected for RSASSA-PSS
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.030 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pss_pss_sha512
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.030 CEST|X509Authentication.java:295|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.030 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pkcs1_sha256
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.030 CEST|X509Authentication.java:295|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.030 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pkcs1_sha384
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.030 CEST|X509Authentication.java:295|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.030 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pkcs1_sha512
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.030 CEST|X509Authentication.java:295|No X.509 cert selected for EC
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.030 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: ecdsa_sha1
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.030 CEST|X509Authentication.java:295|No X.509 cert selected for RSA
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.030 CEST|CertificateMessage.java:1083|Unavailable authentication scheme: rsa_pkcs1_sha1
javax.net.ssl|WARNING|01|main|2021-05-27 12:02:13.030 CEST|CertificateMessage.java:1093|No available authentication scheme
javax.net.ssl|ERROR|01|main|2021-05-27 12:02:13.031 CEST|TransportContext.java:341|Fatal (HANDSHAKE_FAILURE): No available authentication scheme (
"throwable" : {
javax.net.ssl.SSLHandshakeException: No available authentication scheme
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:336)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:283)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.onProduceCertificate(CertificateMessage.java:972)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.produce(CertificateMessage.java:961)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1234)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1170)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:852)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:829)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:920)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:292)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:107)
at TlsServer.start(TlsServer.java:143)
at TlsServer.main(TlsServer.java:95)}
)
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.031 CEST|SSLSessionImpl.java:784|Invalidated session: Session(1622109721099|SSL_NULL_WITH_NULL_NULL)
javax.net.ssl|ALL|01|main|2021-05-27 12:02:13.031 CEST|SSLSessionImpl.java:784|Invalidated session: Session(1622109733001|TLS_AES_128_GCM_SHA256)
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.031 CEST|SSLSocketOutputRecord.java:71|WRITE: TLS13 alert(handshake_failure), length = 2
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.031 CEST|SSLCipher.java:2036|Plaintext before ENCRYPTION (
0000: 02 28 15 00 00 00 00 00 00 00 00 00 00 00 00 00 .(..............
0010: 00 00 00 ...
)
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.032 CEST|SSLSocketOutputRecord.java:85|Raw write (
0000: 17 03 03 00 23 96 86 5D 95 12 6A 81 E7 77 F0 B5 ....#..]..j..w..
0010: 45 7F F3 A4 98 D9 1B E6 FF C7 C1 BC 5F 1B B4 55 E..........._..U
0020: DD 5A FE B9 B1 98 47 CF .Z....G.
)
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.032 CEST|SSLSocketImpl.java:1638|close the underlying socket
javax.net.ssl|DEBUG|01|main|2021-05-27 12:02:13.032 CEST|SSLSocketImpl.java:1657|close the SSL connection (initiative)
javax.net.ssl.SSLHandshakeException: No available authentication scheme
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:336)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:292)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:283)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.onProduceCertificate(CertificateMessage.java:972)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateProducer.produce(CertificateMessage.java:961)
at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.goServerHello(ClientHello.java:1234)
at java.base/sun.security.ssl.ClientHello$T13ClientHelloConsumer.consume(ClientHello.java:1170)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:852)
at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:182)
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:171)
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1418)
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1324)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:440)
at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:829)
at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:920)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:292)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:351)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:107)
at TlsServer.start(TlsServer.java:143)
at TlsServer.main(TlsServer.java:95)
Does anyone know, if I miss something in the configuration?
Solution
Meta: I can't believe this isn't a dupe, but I can't find one.
SSL/TLS authentication uses public-key or asymmetric cryptography not secret-key or symmetric. Instead of this
Key pk = new SecretKeySpec(TEST_KEY.getBytes(StandardCharsets.ISO_8859_1), "RSA");
ks.setKeyEntry("test_key", pk, password, new Certificate[]
{
cert
});
do this
byte[] der = Base64.getDecoder().decode(TEST_KEY.replaceAll("-----(BEGIN|END) PRIVATE KEY-----\r?\n","").replaceAll("\r?\n",""));
// or make these changes already in the value coded as Michael Fehr did
// or leave the internal breaks and use .getMimeDecoder() (but remove the BEGIN/END lines)
PrivateKey pk = KeyFactory.getInstance("RSA") .generatePrivate(new PKCS8EncodedKeySpec(der));
ks.setKeyEntry("test_key", pk, password, new Certificate[]{cert} );
and then use that for KeyManagerFactory.init
as you do now. You don't need to put the server's own cert in its TrustManager, you can just use null
as the first argument to SSLContext.init
, especially since you aren't asking for client auth. However, the client(s) which connect to your server do need this cert added to their truststores; for curl you can just use --cacert $pemfile
on the command line, but other clients will be different and may be more complicated.
PS: the key and cert, and KeyManager and TrustManager if any, can be the same for 1.3 as for earlier protocols, except that DSA can no longer be used in 1.3; only the version and ciphersuites differ. However, in 1.3 you have the option of using a cert restricted to RSA-PSS instead of plain RSA, and when creating from OpenSSL the keyfile also indicates this (although the key needn't be actually restricted).
Answered By - dave_thompson_085
Answer Checked By - Clifford M. (JavaFixing Volunteer)