Akka-streams TLS-PSK support

456 views
Skip to first unread message

Chris Ridmann

unread,
Nov 16, 2015, 5:11:44 PM11/16/15
to Akka User List
Hello everyone,

I am exploring using akka-streams as a TCP client.  Unfortunately my use case requires the usage of pre-shared keys as the cipher suite (specifically TLS_PSK_WITH_AES_128_CBC_SHA) instead of using certificates.

Looking through the source code and test cases, it appears you guys based your SslTls bidi flows off of JSSE.  I am running on jdk 8, and it doesn't look like it supports PSK ciphers:
  
val context = SSLContext.getInstance("TLS")
    context.init(null, null, null)
context
.getDefaultSSLParameters.getCipherSuites.toList.foreach(println)

[info] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
[info] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
[info] TLS_RSA_WITH_AES_128_CBC_SHA256
[info] TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
[info] TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
[info] TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
[info] TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
[info] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
[info] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
[info] TLS_RSA_WITH_AES_128_CBC_SHA
[info] TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
[info] TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
[info] TLS_DHE_RSA_WITH_AES_128_CBC_SHA
[info] TLS_DHE_DSS_WITH_AES_128_CBC_SHA
[info] TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
[info] TLS_ECDHE_RSA_WITH_RC4_128_SHA
[info] SSL_RSA_WITH_RC4_128_SHA
[info] TLS_ECDH_ECDSA_WITH_RC4_128_SHA
[info] TLS_ECDH_RSA_WITH_RC4_128_SHA
[info] TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
[info] TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
[info] TLS_RSA_WITH_AES_128_GCM_SHA256
[info] TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
[info] TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
[info] TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
[info] TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
[info] TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
[info] TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
[info] SSL_RSA_WITH_3DES_EDE_CBC_SHA
[info] TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
[info] TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
[info] SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
[info] SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
[info] SSL_RSA_WITH_RC4_128_MD5
[info] TLS_EMPTY_RENEGOTIATION_INFO_SCSV


val cipherSuites = NegotiateNewSession.withCipherSuites("TLS_PSK_WITH_AES_128_CBC_SHA")
    val clientTls = SslTls(context, cipherSuites, Client)

// eventually produces the following error:

Caused by: java.lang.IllegalArgumentException: Unsupported ciphersuite TLS_PSK_WITH_AES_128_CBC_SHA
[info] at sun.security.ssl.CipherSuite.valueOf(CipherSuite.java:237)
[info] at sun.security.ssl.CipherSuiteList.<init>(CipherSuiteList.java:82)
[info] at sun.security.ssl.SSLEngineImpl.setEnabledCipherSuites(SSLEngineImpl.java:2018)
[info] at akka.stream.impl.io.SslTlsCipherActor$$anonfun$applySessionParameters$1.apply(SslTlsCipherActor.scala:156)


It doesn't seem like I'd be able to integrate bouncycastle as it is a JCE provider instead of JSSE.


I'm relatively new to akka-streams and JSSE, so if I'm mistaken with anything here please let me know!

Do you guys know how I'd go about implementing this use case using akka-streams?

Any help is appreciated - thanks!
-Chris

Jim Hazen

unread,
Nov 16, 2015, 5:41:30 PM11/16/15
to Akka User List
Have you tried adding the BouncyCastleProvider as a security provider?  Then making your normal JSSE calls?

  Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())


Konrad Malawski

unread,
Nov 16, 2015, 5:45:51 PM11/16/15
to akka...@googlegroups.com, Chris Ridmann
Hi Chris,
Jim responded quicker than I managed to; thanks! :-)

I'll add a bit more positive hints to the above suggestion,
it seems that BouncyCastle does implement the cipher you're after:


Read up more infos here: https://www.bouncycastle.org/ 

-- 
Cheers,
Konrad 'ktoso’ Malawski
Akka @ Typesafe
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Chris Ridmann

unread,
Nov 16, 2015, 6:17:10 PM11/16/15
to Akka User List, chris....@gmail.com
Thanks for the quick replies!

Unfortunately I think I'm running into this issue of Bouncycastle being a JCE provider but not a JCCE provider.

E.g.:

val cipherSuites = NegotiateNewSession.withCipherSuites("TLS_PSK_WITH_AES_128_CBC_SHA")
val clientTls = SslTls(SSLContext.getInstance("TLS", new BouncyCastleProvider), cipherSuites, Client)

// will eventually produce (even if I do Security.addProvider(new BouncyCastleProvider) as Jim suggested
[error] Exception in thread "main" java.security.NoSuchAlgorithmException: no such algorithm: TLS for provider BC
[error] at sun.security.jca.GetInstance.getService(GetInstance.java:101)
[error] at sun.security.jca.GetInstance.getInstance(GetInstance.java:218)
[error] at javax.net.ssl.SSLContext.getInstance(SSLContext.java:236)

Jim Hazen

unread,
Nov 17, 2015, 2:37:07 PM11/17/15
to Akka User List, chris....@gmail.com
Hmm.  I'm not an expert here (just use BC for CloudFront).  Have you tried keeping your Java 8 SSLContext while combining that with the BC cipher support?

Something more like your original, but with the BC ciphers.

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())
val context = SSLContext.getInstance("TLS")
context.init(null, null, null)

Chris Ridmann

unread,
Nov 18, 2015, 12:07:01 PM11/18/15
to Akka User List, chris....@gmail.com
Just dug into:
and 

I can confirm the issue is that BC does not implement the required JSSE interfaces.

If I am to use akka-streams using TLS and a PSK cipher, I see 2 options:

1)  Implement JSSE over BC's TLS API for the cipher that I need
2)  Reimplement SslTls in akka-streams to not use JSSE, and to use BC's JCE classes for encryption


The first option seems like a better route, however I'm not familiar enough with the JSSE APIs to actually implement it, so it would require me to spend a bit of time to get familiar with them.  Has anyone done something similar or have any insight into how hard it would be?

If anyone thinks the second option is a better route...let me know!  I'm not sure if akka-streams would benefit from adding support for TLS by not using JSSE, for situations where there is no JSSE provider for a given cipher.
Reply all
Reply to author
Forward
0 new messages