java.security.cert.CertPathValidatorException:Path不与任何信任锚链接

时间:2016-05-18 09:51:19

标签: java ssl x509certificate

我是网络服务新手。我在点击一个URL时收到javax.net.ssl.SSLHandshakeException。信任管理器的代码如下所示。

DatedTrustManager(Date validationDate, StorePkixParameters parameters) {
    this.validationDate = validationDate;
    this.parameters = parameters;
    try {
        validator = CertPathValidator.getInstance("PKIX");
        certFactory = CertificateFactory.getInstance("X.509");
    }
    catch(GeneralSecurityException e) {
        logger.error("error constructing CertPathValidator/CertificateFactory", e);
        throw new IllegalStateException(e);
    }
}

private void validate(X509Certificate[] chain)
        throws CertificateException {
    CertPath certPath = certFactory.generateCertPath(removeExtraCertificates(fixCertificatesOrder(chain)));
    PKIXParameters localParams = parameters.getParams();
    synchronized (validator) {
        localParams.setDate(validationDate!=null ?validationDate :new Date());
        try {
            validator.validate(certPath, localParams);
        } catch (CertPathValidatorException e) {
            logCertificatePathException(e);
            Throwable cause = e.getCause();
            if(cause instanceof CertificateException) {
                throw (CertificateException)cause;
            }
            throw new CertificateException(e);
        } catch (InvalidAlgorithmParameterException e) {
            throw new CertificateException(e);
        }
    }
}

private X509Certificate[] fixCertificatesOrder(X509Certificate[] chain) {

    X509Certificate[] newChain = Arrays.copyOf(chain, chain.length);

    for(int i = 0; i < newChain.length-1; i++) {
        X500Principal issuer = newChain[i].getIssuerX500Principal();
            boolean found = false;
            for(int j = i+2; j < newChain.length; j++) {
                if(issuer.equals(newChain[j].getSubjectX500Principal())) {
                    X509Certificate temp = newChain[i+1];
                    newChain[i+1] = newChain[j];
                    newChain[j] = temp;
                    found = true;
                    break;
                }
            }
            if(!found) {
                return Arrays.copyOf(newChain, i+1);
            }
        }

        if(!isCertificateValid(newChain[i+1])) {
            return Arrays.copyOf(newChain, i+1);
        }
    }
    return newChain;
}

private boolean isCertificateValid(X509Certificate cert) {
    try {
        if(validationDate == null) {
            cert.checkValidity();
        } else {
            cert.checkValidity(validationDate);
        }
        return true;
    }
    catch(CertificateNotYetValidException ex) {
        return false;
    }
    catch(CertificateExpiredException ex) {
        return false;
    }
}

private List<X509Certificate> removeExtraCertificates(X509Certificate[] chain) {
    List<X509Certificate> rc= new ArrayList<X509Certificate>(chain.length);     
    for(X509Certificate cert : chain) {
        rc.add(cert);
        X500Principal subjectX500Principal = cert.getSubjectX500Principal();
        X500Principal issuerX500Principal = cert.getIssuerX500Principal();
        if(subjectX500Principal.equals(issuerX500Principal)) {
            // remove old algorithm that is no longer supported
            // root certificate should be found in trust store
            // 6/21/11 - Opened up to all algorithms (before just cert.getSigAlgName() = "MD2withRSA" or "SHA1withRSA").
            //           Remove all root certificates and expect them to be in the trust store.
            rc.remove(rc.size()-1);
            break;
        }
    }
    return rc;
}

static private void logCertificatePathException(CertPathValidatorException e) {
    CertPath path = e.getCertPath();
    if(path!=null) {
        int idx= e.getIndex();
        if(0<=idx) {
            Certificate certInError = path.getCertificates().get(idx);
            if(certInError instanceof X509Certificate) {
                X509Certificate xcert= (X509Certificate)certInError;
                logger.info("Certificate {} in error - {}", xcert.getSubjectX500Principal(), e.getMessage());
            }
        }
    }
}

@Override
public void checkClientTrusted(X509Certificate chain[], String authType)
        throws CertificateException {
    validate(chain);
}

@Override
public void checkServerTrusted(X509Certificate chain[], String authType)
        throws CertificateException {
    validate(chain);
}

@Override
public X509Certificate[] getAcceptedIssuers() {
    return parameters.getTrustCerts().clone();
}

public Date getValidationDate() {
    return validationDate;
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType,
        Socket socket) throws CertificateException {
    validate(chain);
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType,
        SSLEngine engine) throws CertificateException {
    validate(chain);
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType,
        Socket socket) throws CertificateException {
    validate(chain);
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType,
        SSLEngine engine) throws CertificateException {
    validate(chain);
}

我验证了SSL证书并更新了信任存储,但问题仍然存在。请帮帮我。

0 个答案:

没有答案