java 如何检查证书是否存在于密钥库中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4487445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:35:33  来源:igfitidea点击:

How to check whether a certificate is present in a keystore

javasecuritysslcryptographykeystore

提问by Arun P Johny

I need to verify a signed xml document. As a part of the verification I need to check whether the certificate passed with the signed certificate is a trusted certificate.

我需要验证一个签名的 xml 文档。作为验证的一部分,我需要检查与签名证书一起通过的证书是否是受信任的证书。

All the trusted certificates are added to a keystore called trusted.keystore.

所有受信任的证书都添加到名为 的密钥库中trusted.keystore

How can I check whether the certificate passed is a valid certificate?

如何检查通过的证书是否为有效证书?

I've wrote the following KeySelector, but it is not working

我写了以下内容KeySelector,但它不起作用

import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.Iterator;

import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.KeySelectorException;
import javax.xml.crypto.KeySelectorResult;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.X509Data;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class X509KeySelector extends KeySelector {
    private static Log log = LogFactory.getLog(X509KeySelector.class);

    private KeyStore trustedStore;

    public void setTrustedStore(KeyStore trustedStore) {
        this.trustedStore = trustedStore;
    }

    @SuppressWarnings("rawtypes")
    public KeySelectorResult select(KeyInfo keyInfo,
            KeySelector.Purpose purpose, AlgorithmMethod method,
            XMLCryptoContext context) throws KeySelectorException {
        if (log.isDebugEnabled()) {
            log.debug("Selecting key for algorithm: " + method.getAlgorithm());
        }

        Iterator ki = keyInfo.getContent().iterator();
        while (ki.hasNext()) {
            XMLStructure info = (XMLStructure) ki.next();
            if (log.isDebugEnabled()) {
                log.debug("Found xml structure: " + info.toString());
            }

            if (!(info instanceof X509Data)) {
                if (log.isTraceEnabled()) {
                    log.trace("Ignoring xml structure since it is not a X509Data.");
                }
                continue;
            }

            X509Data x509Data = (X509Data) info;
            Iterator xi = x509Data.getContent().iterator();
            if (log.isDebugEnabled()) {
                log.debug("Iterating X509Data: Size: "
                        + x509Data.getContent().size());
            }

            while (xi.hasNext()) {
                Object o = xi.next();
                if (log.isDebugEnabled()) {
                    log.debug("Found object: " + o);
                }

                if (!(o instanceof X509Certificate)) {
                    if (log.isTraceEnabled()) {
                        log.trace("Ignoring object since it is not a X509Certificate");
                    }
                    continue;
                }
                X509Certificate cert = (X509Certificate) o;
                if (!isTrustedCertificate(cert)) {
                    log.warn("Ignoring certificate since it is not a valid certificate. Certificate: "
                            + cert);
                    continue;
                }

                final PublicKey key = cert.getPublicKey();

                // Make sure the algorithm is compatible
                // with the method.
                if (algEquals(method.getAlgorithm(), key.getAlgorithm())) {
                    KeySelectorResult keySelectorResult = new KeySelectorResult() {
                        public Key getKey() {
                            return key;
                        }
                    };
                    return keySelectorResult;
                } else {
                    log.warn("Ignoring certificate since the algorithms "
                            + method.getAlgorithm() + " and "
                            + key.getAlgorithm() + " does not match.");
                }
            }
        }

        log.error("Unable to find a valid certificate.");
        throw new KeySelectorException("No key found!");
    }

    private boolean isTrustedCertificate(X509Certificate cert) {
        if (trustedStore == null) {
            return true;
        }

        boolean trusted = false;
        try {
            Enumeration<String> aliases = trustedStore.aliases();
            while (aliases.hasMoreElements()) {
                String alias = aliases.nextElement();

                Certificate[] certificates = this.trustedStore
                        .getCertificateChain(alias);
                if (certificates == null) {
                    Certificate certificate = this.trustedStore
                            .getCertificate(alias);
                    if (certificate != null) {
                        certificates = new Certificate[] { certificate };
                    }
                }

                if (certificates != null) {
                    for (Certificate certificate : certificates) {
                        if (!(certificate instanceof X509Certificate)) {
                            continue;
                        }

                        if (cert.getSignature().equals(
                                ((X509Certificate) certificate).getSignature())) {
                            trusted = true;
                            break;
                        }
                    }
                    if (trusted) {
                        break;
                    }
                }
            }
        } catch (KeyStoreException e) {
            log.error(e.toString(), e);
        }
        return trusted;
    }

    static boolean algEquals(String algURI, String algName) {
        if ((algName.equalsIgnoreCase("DSA") && algURI
                .equalsIgnoreCase(SignatureMethod.DSA_SHA1))
                || (algName.equalsIgnoreCase("RSA") && algURI
                        .equalsIgnoreCase(SignatureMethod.RSA_SHA1))) {
            return true;
        } else {
            return false;
        }
    }
}

The problem lies in the method isTrustedCertificate. Where I'm iterating through all the aliases in the keystore and check where it is the same as the passed certificate.

问题出在方法上isTrustedCertificate。我在哪里遍历密钥库中的所有别名并检查它与通过的证书相同的位置。

As the class name suggests it deals with only X509 type certificates.

正如类名所暗示的那样,它只处理 X509 类型证书。

Thank you

谢谢

采纳答案by Arun P Johny

I think I was going the wrong way,

我想我走错了路

I found the verify(PublicKey) method in Certificate object, which will java.security.SignatureException: Signature does not match.exception if the certificates does not match.

我在 Certificate 对象中找到了 verify(PublicKey) 方法,java.security.SignatureException: Signature does not match.如果证书不匹配,它会异常。

回答by gtrig

There is a simpler way to check this using a method that might not be obvious to use at first. The KeyStore class has a method called getCertificateAlias(Certificate cert). If you pass in the certificate you are trying to check for and you do not get a null return, then that certificate is in the KeyStore.

有一种更简单的方法可以使用一开始可能不明显的方法来检查这一点。KeyStore 类有一个名为 getCertificateAlias(Certificate cert) 的方法。如果您传入了您尝试检查的证书,但没有得到 null 返回,则该证书在 KeyStore 中。

Try something like this:

尝试这样的事情:

private boolean isTrustedCertificate(X509Certificate cert) {

  if (trustedStore == null) {
       return true;
  }

  boolean trusted = false;
  try {

     if (cert != null) {

        // Only returns null if cert is NOT in keystore.
        String alias = trustedStore.getCertificateAlias(cert);

        if (alias != null) {
           trusted = true;
        }
     }
  }  catch (KeyStoreException e) {
        log.error(e.toString(), e);
     }

  return trusted;
}