我正在使用REST模板来调用https rest API。
如果我在java.security文件中添加自定义提供程序,我收到以下错误。否则,其余的客户端代码使用rest模板正常工作。我正在添加自定义提供程序,编号为3,即自定义提供程序请求的位置。
org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://10.170.4.86:8070/callback":java.security.ProviderException: java.security.InvalidAlgorithmParameterException: Key format must be RAW; nested exception is javax.net.ssl.SSLException: java.security.ProviderException: java.security.InvalidAlgorithmParameterException: Key format must be RAW
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:580)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:357)
at com.wsclient.RestClient.invokeCallbackURL(RestClient.java:83)
at com.service.processor.CryptoProcessor.processDelayMessage(CryptoProcessor.java:238)
at com.messaging.mdp.MessageReceiver.onDelay(MessageReceiver.java:101)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:269)
at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:327)
at org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:253)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:756)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:679)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:167)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1241)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:660)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1005)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:989)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:82)
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1103)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.net.ssl.SSLException: java.security.ProviderException: java.security.InvalidAlgorithmParameterException: Key format must be RAW
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1889)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1410)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:290)
at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:259)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
java.security的顺序: -
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.4=sun.security.ec.SunEC
security.provider.5=com.sun.net.ssl.internal.ssl.Provider
security.provider.6=com.sun.crypto.provider.SunJCE
security.provider.7=sun.security.jgss.SunProvider
security.provider.8=com.sun.security.sasl.Provider
security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.10=sun.security.smartcardio.SunPCSC
security.provider.3=customProviderImpl
下面的Rest客户端代码: -
ublic class RestClientConfig {
private static final Logger LOG = LoggerFactory
.getLogger(RestClientConfig.class);
@Bean
public RestOperations restOperations(
ClientHttpRequestFactory clientHttpRequestFactory)
throws Exception {
return new RestTemplate(clientHttpRequestFactory);
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory(
@Value("${read.timeout.connector}") String readTimeout,
HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory httpComClientFactory = new HttpComponentsClientHttpRequestFactory(
httpClient);
httpComClientFactory.setConnectTimeout(Integer.parseInt(readTimeout));
httpComClientFactory.setReadTimeout(Integer.parseInt(readTimeout));
return httpComClientFactory;
}
@Bean
public HttpClient getHttpClient(
@Value("${keystore.file}") String keyfile,
@Value("${keystore.pass}") String keypass,
@Value("${keystore.type}") String keystoreType,
@Value("${truststore.file}") String trustfile,
@Value("${truststore.pass}") String trustpass,
@Value("${truststore.type}") String trusttype)
throws Exception {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
KeyStore keyStore = KeyStore.getInstance(keystoreType);
FileInputStream instream = new FileInputStream(new File(keyfile));
try {
keyStore.load(instream, keypass.toCharArray());
}
finally {
instream.close();
}
LOG.debug("trustfile " + trustfile);
KeyStore trustStore = KeyStore.getInstance(trusttype);
instream = new FileInputStream(new File(trustfile));
try {
trustStore.load(instream, trustpass.toCharArray());
}
finally {
instream.close();
}
/*TrustStrategy trustStrategy = new
TrustSelfSignedStrategy();*/
TrustStrategy ts = new TrustStrategy() {
@Override
public boolean isTrusted(
X509Certificate[] x509Certificates, String s)
throws CertificateException {
return true; // TODO : revisit
}
};
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// SSLContext sslcontext1=SSLContext.getInstance("", "");
// sslcontext1.in
SSLContext sslcontext = org.apache.http.ssl.SSLContexts.custom()
.loadKeyMaterial(keyStore, keypass.toCharArray())
.loadTrustMaterial(trustStore, ts)
.build();
final HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(
String arg0, SSLSession arg1) {
return true;
}
};
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, new String[] {
"TLSv1.2" }, null,
SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
/*SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, new String[] { "TLSv1.2" }, null,
hv);*/
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
答案 0 :(得分:0)
当安装SDK请求将其安全提供程序列在java.security的第三个位置时,我遇到了类似的错误。在连接请求期间,应用程序开始显示以下异常:
Caused by: javax.net.ssl.SSLException: java.security.ProviderException: java.security.InvalidAlgorithmParameterException: Key format must be RAW
at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1906)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1889)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1410)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1546)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.getResponseCode(URLConnectionHTTPConduit.java:260)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1529)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1502)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1309)
... 16 more
Caused by: java.security.ProviderException: java.security.InvalidAlgorithmParameterException: Key format must be RAW
at sun.security.ssl.Handshaker.calculateMasterSecret(Handshaker.java:1175)
at sun.security.ssl.Handshaker.calculateKeys(Handshaker.java:1110)
at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1078)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
... 27 more
Caused by: java.security.InvalidAlgorithmParameterException: Key format must be RAW
at com.sun.crypto.provider.TlsMasterSecretGenerator.engineInit(TlsMasterSecretGenerator.java:67)
at javax.crypto.KeyGenerator.init(KeyGenerator.java:454)
at javax.crypto.KeyGenerator.init(KeyGenerator.java:430)
at sun.security.ssl.Handshaker.calculateMasterSecret(Handshaker.java:1163)
... 35 more
一旦我将该提供程序移动到java.security中提供程序列表的底部,连接就完美了。 至少在SSLProvider之后移动CustomProvider,因为在连接握手期间,从CustomProvider而不是SSLProvider调用函数