我需要驗證簽名的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類型的證書。
謝謝