InvalidAlgorithmParameterException: Key format must be RAW with REST template and Spring4

断了今生、忘了曾经 提交于 2019-12-12 04:16:41

问题


I am using REST template to invoke https rest APIs.

I am getting the below error, if i add a custom provider in java.security file. Otherwise the rest client code is working fine using rest template. I am adding the custom provider at number 3, the requested position by the custom provider.

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)

The order of 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

The Rest client code below:-

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:


I got a similar error when the installation of an SDK requested that their security provider to be listed in the third position in java.security. During connection requests the app started to display these exceptions:

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

Once I moved that provider at the bottom of the list of providers in java.security, connection worked perfectly fine. At least move the CustomProvider after the SSLProvider because during the connection handshake a function is called from the CustomProvider instead of SSLProvider



来源:https://stackoverflow.com/questions/40496778/invalidalgorithmparameterexception-key-format-must-be-raw-with-rest-template-an

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!