Java SSL/TLS ignore expired cert? (java.security.cert.CertPathValidatorException: timestamp check failed)

匿名 (未验证) 提交于 2019-12-03 02:49:01

问题:

I am having an issue with a api that I communicate to via SSL. I am thinking the exception is coming due to the fact that the SSL cert has expired. The problem is that I do not administer the API box. Is it possible to ignore expired certificates?

Exception:

[ERROR,TaacWorkshop] Problem deleting user group from CADA:  org.apache.thrift.transport.TTransportException: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed     at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:156)     at company.oss.thrift.cada.CADABackend$Client.send_DeleteUserGroup(CADABackend.java:580)     at company.oss.thrift.cada.CADABackend$Client.DeleteUserGroup(CADABackend.java:568)     at com.cable.company.nse.cada.CadaDao.deleteUserGroup(CadaDao.java:72)     at com.cable.company.nse.taac.business.TaacWorkshop.deleteTaac(TaacWorkshop.java:127)     at com.cable.company.nse.taac.controller.RemoteVendorAccessController.processRequest(RemoteVendorAccessController.java:130)     at com.cable.company.nse.taac.controller.RemoteVendorAccessController$$FastClassByCGLIB$$63639bdf.invoke(<generated>)     at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)     at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)     at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:67)     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)     at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)     at com.cable.company.nse.taac.controller.RemoteVendorAccessController$$EnhancerByCGLIB$$bdd8aaad.processRequest(<generated>)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)     at java.lang.reflect.Method.invoke(Method.java:592)     at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:710)     at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:167)     at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:414)     at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:402)     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)     at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:563)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)     at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:109)     at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)     at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)     at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)     at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)     at java.lang.Thread.run(Thread.java:613) Caused by: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1232)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkWrite(SSLSocketImpl.java:1244)     at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:43)     at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)     at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)     at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:154)     ... 66 more Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1584)     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)     at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)     at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)     at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:618)     at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)     at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)     at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)     at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:154)     at company.oss.thrift.cada.CADABackend$Client.send_CreateUserGroup(CADABackend.java:546)     at company.oss.thrift.cada.CADABackend$Client.CreateUserGroup(CADABackend.java:534)     at com.cable.company.nse.cada.CadaDao.createUserGroup(CadaDao.java:93)     at com.cable.company.nse.taac.business.TaacWorkshop.createTaac(TaacWorkshop.java:210)     at com.cable.company.nse.taac.controller.RemoteVendorAccessController.processRequest(RemoteVendorAccessController.java:111)     ... 61 more Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: timestamp check failed     at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:187)     at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:130)     at sun.security.validator.Validator.validate(Validator.java:203)     at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)     at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)     ... 76 more Caused by: java.security.cert.CertPathValidatorException: timestamp check failed     at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139)     at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:316)     at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178)     at java.security.cert.CertPathValidator.validate(CertPathValidator.java:206)     at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:182)     ... 81 more Caused by: java.security.cert.CertificateExpiredException: NotAfter: Sat Jul 17 13:44:42 MDT 2010     at sun.security.x509.CertificateValidity.valid(CertificateValidity.java:256)     at sun.security.x509.X509CertImpl.checkValidity(X509CertImpl.java:570)     at sun.security.provider.certpath.BasicChecker.verifyTimestamp(BasicChecker.java:157)     at sun.security.provider.certpath.BasicChecker.check(BasicChecker.java:109)     at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:117)     ... 85 more 

The current code has to be able to set a trust store, because there is a Client cert authentication. I have tried the below suggestions, but still run into some problem. Here is the current code I use:

        KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());         ClassPathResource keystore = new ClassPathResource(cadaBackendCertFile);          identityStore.load(keystore.getInputStream(), cadaBackendCertFilePassword.toCharArray());          KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());         kmf.init(identityStore, cadaBackendCertFilePassword.toCharArray());          TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());         tmf.init(identityStore);          SSLContext ctx = SSLContext.getInstance("TLS");         ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());          SSLSocketFactory fac = ctx.getSocketFactory();         Socket sslsock = fac.createSocket(cadaBackendEndpoint, cadaBackendPort);         TTransport transport = new TSocket(sslsock); 

Changed that code to the following, and am getting server issues, but it fixed my problem with the security exception:

        KeyStore identityStore = KeyStore.getInstance(KeyStore.getDefaultType());         ClassPathResource keystore = new ClassPathResource(cadaBackendCertFile);          identityStore.load(keystore.getInputStream(), cadaBackendCertFilePassword.toCharArray());          KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());         kmf.init(identityStore, cadaBackendCertFilePassword.toCharArray());          TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());         tmf.init(identityStore);          SSLContext ctx = SSLContext.getInstance("TLS");         ctx.init(kmf.getKeyManagers(), new TrustManager[] {new X509TrustManager(){             public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {             }             public void checkServerTrusted(X509Certificate[] chain,String authType) throws CertificateException {                            }             public X509Certificate[] getAcceptedIssuers() {                 return null;             }                }}, new SecureRandom());          SSLSocketFactory fac = ctx.getSocketFactory();         Socket sslsock = fac.createSocket(cadaBackendEndpoint, cadaBackendPort);         TTransport transport = new TSocket(sslsock);          TProtocol proto = new TBinaryProtocol(transport);         cadaBackendClient = new Client(proto); 

Actually - even that above code throws an exception:

ERROR[com.cable.nse.cada.CadaDaoTest][main] - Error: org.apache.thrift.transport.TTransportException: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate     at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:156)     at .oss.thrift.cada.CADABackend$Client.send_UserDetails(CADABackend.java:328)     at .oss.thrift.cada.CADABackend$Client.UserDetails(CADABackend.java:316)     at com.cable.nse.cada.CadaDao.getUserDetails(CadaDao.java:136)     at com.cable.nse.cada.CadaDaoTest.testCada(CadaDaoTest.java:73)     at com.cable.nse.cada.CadaDaoTest.test(CadaDaoTest.java:37)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)     at java.lang.reflect.Method.invoke(Method.java:592)     at junit.framework.TestCase.runTest(TestCase.java:154)     at junit.framework.TestCase.runBare(TestCase.java:127)     at junit.framework.TestResult$1.protect(TestResult.java:106)     at junit.framework.TestResult.runProtected(TestResult.java:124)     at junit.framework.TestResult.run(TestResult.java:109)     at junit.framework.TestCase.run(TestCase.java:118)     at junit.framework.TestSuite.runTest(TestSuite.java:208)     at junit.framework.TestSuite.run(TestSuite.java:203)     at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)     at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:117)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1650)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:618)     at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)     at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)     at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)     at org.apache.thrift.transport.TIOStreamTransport.flush(TIOStreamTransport.java:154)     ... 23 more 

回答1:

It is not safe to alter the default SSLContext since it affects the entire process. This lowers the security setting of every connection indiscriminately. It may also not be thread-safe although I am not sure.

I recommend delegating such operations to a separate process per-request.

String content = new HttpsNoVerify.fetch(URL.create(myURL)); 

Listing of com/example/HttpsNoVerify.java:

package com.example;  import org.apache.commons.io.IOUtils;  import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.net.URL;  public class HttpsNoVerify {     public static void main(String... args) throws Exception {         URL url = new URL(args[0]);          TrustManager[] trustAllCerts = new TrustManager[]{             new X509TrustManager() {                 public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}                 public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType){}                 public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType){}             }         };          SSLContext sc = SSLContext.getInstance("SSL");         sc.init(null, trustAllCerts, new java.security.SecureRandom());         HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());          IOUtils.copy(url.openStream(), System.out);     }      public String fetch(URL url) throws Exception {         return new SubProcess(HttpsNoVerify.class).run(url.toString());     } } 

Listing of com/example/SubProcess.java:

package com.example;  import org.apache.commons.io.IOUtils;  import java.util.Arrays;  public class SubProcess {     private final Class<?> classToRun;      public SubProcess(Class<?> classToRun) {         this.classToRun = classToRun;     }      public String run(String... args) throws Exception {         ProcessBuilder processBuilder = new ProcessBuilder("java",                 "-Djava.library.path=" + System.getProperty("java.library.path"),                 "-classpath", System.getProperty("java.class.path"),                 classToRun.getCanonicalName());          for (String arg : args) processBuilder.command().add(arg);          processBuilder.redirectErrorStream();          Process process = processBuilder.start();          String output = IOUtils.toString(process.getInputStream());          process.waitFor();          if (process.exitValue() != 0)             throw new IllegalStateException(                     String.format("Running %s with %s failed", classToRun, Arrays.toString(args)));          return output;     } } 


回答2:

I'm not aware of a property that would let you ignore the time validity check on the remote certificate for the default X509TrustManagers, but if you have access to the client code, you can probably configure a different SSLContext with your own X509TrustManager, within which you could catch this exception.

If you want to use something like jSSLutils and its SSLContextFactory, you could write a wrapper along these lines:

PKIXSSLContextFactory sslContextFactory = new PKIXSSLContextFactory(); sslContextFactory.setTrustManagerWrapper(new X509TrustManagerWrapper() {     @Override     public X509TrustManager wrapTrustManager(final X509TrustManager origManager) {         return new X509TrustManager() {              @Override             public X509Certificate[] getAcceptedIssuers() {                 return origManager.getAcceptedIssuers();             }              @Override             public void checkServerTrusted(X509Certificate[] chain,                                                    String authType)                     throws CertificateException {                 try {                     origManager.checkServerTrusted(chain, authType);                 } catch (CertificateExpiredException e) {                     // TODO log or do something else to rethrow                                     // the exception if chain[0] isn't the certificate                                     // for which you want to make this special case.                 }             }              @Override             public void checkClientTrusted(X509Certificate[] chain,                                                    String authType)                     throws CertificateException {                 origManager.checkClientTrusted(chain, authType);             }         };     } }); SSLContext sslContext = sslContextFactory.buildSSLContext(); 

Making use of this SSLContext then really depends on what uses SSL in your application. In the worst case, you can configure it globally using SSLContext.setDefault(sslContext) with Java 6 and above. Otherwise, some libraries will let you configure an SSLContext.



回答3:

i think you can download the cert and add it to your store. You then configure your jvm with environment properties to indicate where the store is.



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