关于Certificates does not conform to algorithm constraints

在我们自己的项目中由于代码重构以及升级,将jdk环境从jdk1.6换成了1.7,这时候我们发现了一个问题,访问某些https网站时候,出现了Certificates does not conform to algorithm constraints的异常,上网搜索了下,没有什么现成的解决方案,倒是找到了一些原因,具体原因可以看下面的链接

http://stackoverflow.com/questions/14149545/java-security-cert-certificateexception-certificates-does-not-conform-to-algori

总的来说在1.7这个问题其实已经修补了,但是如果有一些类实现了X509TrustManager这个接口,而不是extends X509ExtendedTrustManager 这个抽象类,那么jdk底层会使用AbstractTrustManagerWrapper这个类来包裹实现X509TrustManager接口的类,当使用这个wrapper的时候,一定程度上有时候会绕过已经被修复的问题,导致Certificates does not conform to algorithm constraints会再度复现。所以解决方案就有了

在httpclient中我们实现sslcontext和sslcontextbuilder 在sslcontextbuilder里我们使用自己的trustmanager类去extends X509ExtendedTrustManager 具体代码如下:

private static SSLConnectionSocketFactory buildSSLConnectionFactory()
        throws FileNotFoundException, KeyStoreException,
        NoSuchAlgorithmException, KeyManagementException {

    SSLContext sslContext = new MySSLContextBuilder().useTLS().loadTrustMaterial(null, new TrustStrategy()
            {
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            })
            .build();

    return new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
}

static class MySSLContext extends SSLContext {
    public MySSLContext(SSLContextSpi sslContextSpi, Provider provider, String s) {
        super(sslContextSpi, provider, s);
    }

    public static SSLContextBuilder custom() {
        return new MySSLContextBuilder();
    }
}

static class MySSLContextBuilder extends SSLContextBuilder {
    static final String TLS   = "TLS";
    static final String SSL   = "SSL";

    private String protocol;
    private Set<KeyManager> keymanagers;
    private Set<TrustManager> trustmanagers;
    private SecureRandom secureRandom;


    public MySSLContextBuilder() {
        super();
        this.keymanagers = new HashSet<KeyManager>();
        this.trustmanagers = new HashSet<TrustManager>();
    }

    static class TrustManagerDelegate extends X509ExtendedTrustManager {

        private final X509TrustManager trustManager;
        private final TrustStrategy trustStrategy;

        TrustManagerDelegate(final X509TrustManager trustManager, final TrustStrategy trustStrategy) {
            super();
            this.trustManager = trustManager;
            this.trustStrategy = trustStrategy;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException {

        }

        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException {

        }

        public void checkClientTrusted(
                final X509Certificate[] chain, final String authType) throws CertificateException {
            this.trustManager.checkClientTrusted(chain, authType);
        }

        public void checkServerTrusted(
                final X509Certificate[] chain, final String authType) throws CertificateException {
            if (!this.trustStrategy.isTrusted(chain, authType)) {
                this.trustManager.checkServerTrusted(chain, authType);
            }
        }

        public X509Certificate[] getAcceptedIssuers() {
            return this.trustManager.getAcceptedIssuers();
        }

    }

    public SSLContextBuilder loadTrustMaterial(
            final KeyStore truststore,
            final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException {
        final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
        tmfactory.init(truststore);
        final TrustManager[] tms = tmfactory.getTrustManagers();
        if (tms != null) {
            if (trustStrategy != null) {
                for (int i = 0; i < tms.length; i++) {
                    final TrustManager tm = tms[i];
                    if (tm instanceof X509TrustManager) {
                        tms[i] = new MySSLContextBuilder.TrustManagerDelegate(
                                (X509TrustManager) tm, trustStrategy);
                    }
                }
            }
            for (final TrustManager tm : tms) {
                this.trustmanagers.add(tm);
            }
        }
        return this;
    }
}

···

    原文作者:语文报
    原文地址: https://www.jianshu.com/p/61a2327a8b14
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞