1

I have the following code:

SSLContext sslContext = SSLContext.getInstance("TLS", BouncyCastleProvider.PROVIDER_NAME);
sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
SSLEngine sslEngine = sslContext.createSSLEngine();
String[] suites = { "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" };
sslEngine.setEnabledCipherSuites(suites);

Thanks.

EDIT: I found that I should use BouncyCastleJsseProvider which require a SecureRandom object, like this:

sslContext.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());

After using the new provider, I'm getting the following stacktrace in my code base, as I understand, it should work as before:

Aug 17, 2017 8:47:32 PM org.bouncycastle.jsse.provider.ProvTlsServer notifyAlertRaised
INFO: Server raised fatal(2) handshake_failure(40) alert: Failed to read record
org.bouncycastle.tls.TlsFatalAlert: handshake_failure(40)
    at org.bouncycastle.tls.AbstractTlsServer.getSelectedCipherSuite(Unknown Source)
    at org.bouncycastle.jsse.provider.ProvTlsServer.getSelectedCipherSuite(Unknown Source)
    at org.bouncycastle.tls.TlsServerProtocol.sendServerHelloMessage(Unknown Source)
    at org.bouncycastle.tls.TlsServerProtocol.handleHandshakeMessage(Unknown Source)
    at org.bouncycastle.tls.TlsProtocol.processHandshakeQueue(Unknown Source)
    at org.bouncycastle.tls.TlsProtocol.processRecord(Unknown Source)
    at org.bouncycastle.tls.RecordStream.readRecord(Unknown Source)
    at org.bouncycastle.tls.TlsProtocol.safeReadRecord(Unknown Source)
    at org.bouncycastle.tls.TlsProtocol.offerInput(Unknown Source)
    at org.bouncycastle.jsse.provider.ProvSSLEngine.unwrap(Unknown Source)
AlexITC
  • 1,054
  • 1
  • 10
  • 21

1 Answers1

5

I did the following in order to get it working.

  • Add providers: BouncyCastleProvider and BouncyCastleJsseProvider

    Security.addProvider(new BouncyCastleProvider());
    Security.addProvider(new BouncyCastleJsseProvider());
    
  • Create SSLContext using BouncyCastleJsseProvider

    SSLContext sslContext = SSLContext.getInstance("TLS", BouncyCastleJsseProvider.PROVIDER_NAME);
    
  • Initialize the sslContext using an instance of SecureRandom with BouncyCastleProvider

    sslContext.init(
            keyManagers,
            trustManagers,
            SecureRandom.getInstance("DEFAULT", BouncyCastleProvider.PROVIDER_NAME));
    
  • You might need to create the KeyManagerFactory with BouncyCastleJsseProvider and PKIX algorithm

    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("PKIX", BouncyCastleJsseProvider.PROVIDER_NAME);
    
  • Now, we are able to enable the cipher suite

    SSLEngine sslEngine = sslContext.createSSLEngine();
    String[] suites = { "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8" };
    sslEngine.setEnabledCipherSuites(suites);
    
AlexITC
  • 1,054
  • 1
  • 10
  • 21
  • 1
    Thank you! I had done all the necessary, except for adding the BCJSSE *and* the BCJCE provider! Sigh! For what it is worth, the only place where you need to specify the BouncyCastle Provider when getting instances, is when getting the SSLContext instance. The rest can be the default ones returned. – Rogan Dawes Oct 02 '17 at 11:38