2

署名されたxmlドキュメントを確認する必要があります。検証の一環として、署名された証明書とともに渡された証明書が信頼できる証明書であるかどうかを確認する必要があります。

すべての信頼できる証明書は、と呼ばれるキーストアに追加されますtrusted.keystore

渡された証明書が有効な証明書であるかどうかを確認するにはどうすればよいですか?

私は次のように書いた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;
        }
    }
}

問題はメソッドにありますisTrustedCertificate。キーストア内のすべてのエイリアスを反復処理し、渡された証明書と同じであるかどうかを確認します。

クラス名が示すように、X509型式証明書のみを扱います。

ありがとうございました

4

2 に答える 2

2

最初はわかりにくい方法を使用して、これを確認する簡単な方法があります。KeyStoreクラスには、getCertificateAlias(Certificate cert)というメソッドがあります。チェックしようとしている証明書を渡してもnullが返されない場合、その証明書はKeyStoreにあります。

次のようなものを試してください。

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;
}
于 2013-05-08T18:01:00.917 に答える
1

私は間違った方向に進んでいたと思います、

Certificateオブジェクトにverify(PublicKey)メソッドが見つかりました。これはjava.security.SignatureException: Signature does not match.、証明書が一致しない場合は例外になります。

于 2010-12-20T07:29:50.253 に答える