开发者

How to check whether a certificate is present in a keystore

开发者 https://www.devze.com 2023-01-31 04:55 出处:网络
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.

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.

All the trusted certificates are added to a keystore called 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

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.

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

Thank you


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.

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;
}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号