当同时且足够快地运行Resteasy客户端(版本3.0.6.Final)时,我总是得到:
Caused by: javax.net.ssl.SSLException: Received fatal alert: bad_record_mac
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208) ~[na:1.7.0_09]
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) ~[na:1.7.0_09]
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1977) ~[na:1.7.0_09]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1093) ~[na:1.7.0_09]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1328) ~[na:1.7.0_09]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355) ~[na:1.7.0_09]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) ~[na:1.7.0_09]
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:533) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:401) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:178) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:304) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:610) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:445) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) ~[httpclient-4.3.1.jar:4.3.1]
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57) ~[httpclient-4.3.1.jar:4.3.1]
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283) ~[resteasy-client-3.0.6.Final.jar:na]
... 20 common frames omitted
此类问题从未出现在常规调用(低并发)中,因此SSL初始化应该没问题:
// load the certificate
InputStream fis = this.getClass().getResourceAsStream("/path/to/redlink-CA.crt");
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(fis);
// load the keystore that includes self-signed cert as a "trusted" entry
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
keyStore.setCertificateEntry("CA", cert);
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
// build the rest client
ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder();
clientBuilder.sslContext(ctx);
所以我没有想法如何找到这个问题的来源,这很难调试。