在使用libcoap(4.2.0rc3)编译出来的coap-client连接Californium建立的CoapServer时,会出现无法连接的问题,报以下的错误。

org.eclipse.californium.scandium.dtls.HandshakeException: Client proposed unsupported cipher suites only

抓包发现,CoapClient会发送以下的Cipher Suites

Cipher Suites (14 suites)
    Cipher Suite: TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xccac)
    Cipher Suite: TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA (0xc036)
    Cipher Suite: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA (0xc035)
    Cipher Suite: TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA (0xc034)
    Cipher Suite: TLS_PSK_WITH_AES_256_GCM_SHA384 (0x00a9)
    Cipher Suite: TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 (0xc08f)
    Cipher Suite: TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 (0xccab)
    Cipher Suite: TLS_PSK_WITH_AES_256_CCM (0xc0a5)
    Cipher Suite: TLS_PSK_WITH_AES_256_CBC_SHA (0x008d)
    Cipher Suite: TLS_PSK_WITH_AES_128_GCM_SHA256 (0x00a8)
    Cipher Suite: TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 (0xc08e)
    Cipher Suite: TLS_PSK_WITH_AES_128_CCM (0xc0a4)
    Cipher Suite: TLS_PSK_WITH_AES_128_CBC_SHA (0x008c)
    Cipher Suite: TLS_PSK_WITH_3DES_EDE_CBC_SHA (0x008b)

而Californium/Scandium支持的Cipher Suites定义中没有这几种

public enum CipherSuite {
	
	// Cipher suites //////////////////////////////////////////////////
	
	TLS_NULL_WITH_NULL_NULL(0x0000, KeyExchangeAlgorithm.NULL, Cipher.NULL, MACAlgorithm.NULL),
	TLS_PSK_WITH_AES_128_CBC_SHA256(0x00AE, KeyExchangeAlgorithm.PSK, Cipher.AES_128_CBC, MACAlgorithm.HMAC_SHA256),
	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(0xC023, KeyExchangeAlgorithm.EC_DIFFIE_HELLMAN, Cipher.AES_128_CBC, MACAlgorithm.HMAC_SHA256),
	TLS_PSK_WITH_AES_128_CCM_8(0xC0A8, KeyExchangeAlgorithm.PSK, Cipher.AES_128_CCM_8, MACAlgorithm.NULL),
	TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8(0xC0AE, KeyExchangeAlgorithm.EC_DIFFIE_HELLMAN, Cipher.AES_128_CCM_8, MACAlgorithm.NULL);

出现问题的LibCoAP是使用GnuTLS作为DTLS连接库的,的确没有支持Californium/Scandium定义的这几种。

解决方案:

  1. 自己给Scandium加上Cipher Suites
  2. LibCoAP使用TinyDTLS或OpenSSL重新编译一遍,TinyDTLS支持Scandium定义的CipherSuites

这里使用第1种解决方案,给CipherSuite类加上以下内容并重新编译

	TLS_PSK_WITH_AES_256_CBC_SHA(0x008D, KeyExchangeAlgorithm.PSK, Cipher.AES_256_CBC, MACAlgorithm.HMAC_SHA1),
	TLS_PSK_WITH_AES_128_CBC_SHA(0x008C, KeyExchangeAlgorithm.PSK, Cipher.AES_128_CBC, MACAlgorithm.HMAC_SHA1),

重新编译并启动server,再用coap-client连接,发现还是有问题

# ./coap-client -m get coaps://192.168.33.240:5684/ -u password -k sesame
Jan 04 08:21:51 WARN do_gnutls_handshake: session establish returned -58: 'An illegal TLS extension was received.'
Jan 04 08:21:52 WARN do_gnutls_handshake: session establish returned -10: 'The specified session has been invalidated for some reason.'
Jan 04 08:21:54 WARN do_gnutls_handshake: session establish returned -10: 'The specified session has been invalidated for some reason.'

在Java代码中显示 java.security.InvalidKeyException: Illegal key size。Google发现是JDK包的问题,参考https://blog.csdn.net/wangjunjun2008/article/details/50847426 进行了解决。再次启动,终于可以顺利连接成功。

# ./coap-client -m get coaps://192.168.33.240:5684/ -u password -k sesame
************************************************************
CoAP RFC 7252
************************************************************
This server is using the Eclipse Californium (Cf) CoAP framework
published under EPL+EDL: http://www.eclipse.org/californium/

(c) 2014, 2015, 2016 Institute for Pervasive Computing, ETH Zurich and others
************************************************************