InvalidAlgorithmParameterException:密钥格式必须是REST模板和Spring4

时间:2016-11-08 21:31:47

标签: java spring rest security resttemplate

我正在使用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();
  }

1 个答案:

答案 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调用函数