关于SSLHandshakeException存在许多问题,但我仍面临着其中一个问题。我是SSL / TLS的绝对初学者,实际上是安全性。
我的问题:
我正在使用Java Eclipse Paho mqtt库(windows7,oracle jdk1.8.0_65)。我的mqtt客户端应该使用安全通道连接到mqtt代理。我基本上使用this解决方案进行小修改,以利用最新的Bouncy Castle库from here。在那里,我读到了从IT获得的文件(*.pem
CA证书,*.crt
客户端证书和*.key
文件),以设置TrustManagerFactory
,{{1}并最终创建KeyManagerFactory
以在SSLContext
中设置SocketFactory
。
当打开SSL调试并尝试连接时,我会观察以下握手操作:
MqttConnectionOptions
客户端发送问候语:
ssl://myserver.org:8883
adding as trusted cert:
...
***
found key for : private-key
chain[0]
...
服务器发送hello:
*** ClientHello, TLSv1.2
RandomCookie: GMT: 1447336773 bytes = { .. , .. }
...
现在服务器通过证书链后,我得到以下内容:
*** ServerHello, TLSv1.2
RandomCookie: GMT: 572699079 bytes = { .. , .. } -- (strange time stamp here)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
Extension elliptic_curves, curve names: {secp256r1}
Extension ec_point_formats, formats: [uncompressed]
***
%% Initialized: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
** TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
MQTT Con: TESTCLIENT1, READ: TLSv1.2 Handshake, length = 6544
*** Certificate chain
chain [0] = [
...
之后似乎只有另一次尝试,客户端只发送另一个***
%% Invalidated: [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
MQTT Con: TESTCLIENT1, SEND TLSv1.2 ALERT: fatal, description = certificate_unknown
MQTT Con: TESTCLIENT1, WRITE: TLSv1.2 Alert, length = 2
MQTT Con: TESTCLIENT1, called closeSocket()
MQTT Con: TESTCLIENT1, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
MQTT Con: TESTCLIENT1, called close()
MQTT Con: TESTCLIENT1, called closeInternal(true)
...
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
MQTT Con: TESTCLIENT1, setSoTimeout(30000) called
服务器再次使用*** ClientHello, TLSv1.2
回答。但我没有收到预期的*** ServerHello, TLSv1.2
。
我尝试过的解决方案:
1。)使用Java *** ServerHelloDone
我将keytool -importcert -alias ca-file.alias -file myPem.pem
导入我的信任库*.pem
(我甚至不知道是否需要这样做)。
2。)我尝试跟进this解决方案,该解决方案只删除了cacerts
,并且让我更进一步:
TrustManager
它似乎确实让我通过但是1.)那不是它应该如何以及2.)然后mqtt客户端在第一次***
MQTT Con: TESTCLIENT1, READ: TLSv1.2 Handshake, length = 333
*** ECDH ServerKeyExchange
Signature Algorithm SHA1withRSA
...
*** CertificateRequest
Cert Types: RSA
Supported Signature Algorithms: SHA1withRSA, SHA256withRSA, SHA384withRSA, SHA512withRSA
Cert Authorities:
<Empty>
MQTT Con: TESTCLIENT1, READ: TLSv1.2 Handshake, length = 4
*** ServerHelloDone
matching alias: private-key
*** Certificate chain
chain [0] = [
...
*** ECDHClientKeyExchange
...
*** CertificateVerify
...
*** Finished
调用后才返回。
我现在的问题是:
publish
,TrustManagerFactory
等在Java中正确处理证书和密钥文件?