Skip to content

Instantly share code, notes, and snippets.

@kjunichi
Created August 16, 2024 09:52
Show Gist options
  • Save kjunichi/c517c3b9c37552d9f1ba38280c2da94c to your computer and use it in GitHub Desktop.
Save kjunichi/c517c3b9c37552d9f1ba38280c2da94c to your computer and use it in GitHub Desktop.
import java.nio.file.Paths;
import java.security.Key;
import java.security.KeyException;
import java.security.PublicKey;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.List;
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.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyValue;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class Main {
public void execute() throws Exception {
System.out.println("start");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(Paths.get("test2.xml").toFile());
//document.normalizeDocument();
// Element languageList = document.getDocumentElement();
//System.out.println(document.toString());
//System.out.println(document.getTextContent());
// 署名要素(Signature)の特定
Element sigNode = (Element) document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature").item(0);
//System.out.println(XMLSignature.XMLNS);
// System.out.println(sigNode.getTextContent());
String svalue = (String) sigNode.getElementsByTagName("SignatureValue").item(0).getTextContent();
System.out.println(svalue);
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
// DOMValidateContext valContext = new DOMValidateContext(new KeyValueKeySelector(), sigNode);
//RawX509KeySelector
DOMValidateContext valContext = new DOMValidateContext(new RawX509KeySelector(), sigNode);
System.out.println("valCon");
// unmarshal the XMLSignature
XMLSignature signature = fac.unmarshalXMLSignature(valContext);
System.out.println("XMLSignature");
// Validate the XMLSignature (generated above)
boolean coreValidity = signature.validate(valContext);
System.out.println(coreValidity);
System.out.println("end");
}
public static void main(String[] args) {
Main m = new Main();
try {
m.execute();
} catch (Exception e) {
System.out.println(e);
}
}
private static class KeyValueKeySelector extends KeySelector {
public KeySelectorResult select(KeyInfo keyInfo,
KeySelector.Purpose purpose,
AlgorithmMethod method,
XMLCryptoContext context)
throws KeySelectorException {
if (keyInfo == null) {
throw new KeySelectorException("Null KeyInfo object!");
}
System.out.println("keyInfo != null");
SignatureMethod sm = (SignatureMethod) method;
List<XMLStructure> list = keyInfo.getContent();
for (int i = 0; i < list.size(); i++) {
System.out.println("i = "+i);
XMLStructure xmlStructure = list.get(i);
if (xmlStructure instanceof X509Data) {
System.out.println(xmlStructure);
for(Object x509Content: ((X509Data)xmlStructure).getContent()) {
X509Certificate cert = (X509Certificate)x509Content;
System.out.println(cert.getPublicKey().toString());
return new SimpleKeySelectorResult(cert.getPublicKey());
}
}
if (xmlStructure instanceof KeyValue) {
System.out.println("xmlStructure instanceof KeyValue");
PublicKey pk = null;
try {
pk = ((KeyValue) xmlStructure).getPublicKey();
} catch (KeyException ke) {
throw new KeySelectorException(ke);
}
// make sure algorithm is compatible with method
if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) {
return new SimpleKeySelectorResult(pk);
}
} else {
System.out.println("");
}
}
System.out.println("Dame");
throw new KeySelectorException("No KeyValue element found!");
}
static boolean algEquals(String algURI, String algName) {
if (algName.equalsIgnoreCase("DSA") &&
algURI.equalsIgnoreCase("http://www.w3.org/2009/xmldsig11#dsa-sha256")) {
return true;
} else if (algName.equalsIgnoreCase("RSA") &&
algURI.equalsIgnoreCase("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")) {
return true;
} else {
System.out.println("alg Ng");
return false;
}
}
}
public static class RawX509KeySelector extends KeySelector {
public KeySelectorResult select(KeyInfo keyInfo,
KeySelector.Purpose purpose,
AlgorithmMethod method,
XMLCryptoContext context)
throws KeySelectorException {
if (keyInfo == null) {
throw new KeySelectorException("Null KeyInfo object!");
}
// search for X509Data in keyinfo
Iterator<?> iter = keyInfo.getContent().iterator();
while (iter.hasNext()) {
XMLStructure kiType = (XMLStructure) iter.next();
if (kiType instanceof X509Data) {
X509Data xd = (X509Data) kiType;
Object[] entries = xd.getContent().toArray();
X509CRL crl = null;
// Looking for CRL before finding certificates
for (int i = 0; (i < entries.length && crl == null); i++) {
if (entries[i] instanceof X509CRL) {
crl = (X509CRL) entries[i];
}
}
Iterator<?> xi = xd.getContent().iterator();
while (xi.hasNext()) {
Object o = xi.next();
// skip non-X509Certificate entries
if (o instanceof X509Certificate) {
if ((purpose != KeySelector.Purpose.VERIFY) &&
(crl != null) &&
crl.isRevoked((X509Certificate)o)) {
continue;
} else {
return new SimpleKeySelectorResult
(((X509Certificate)o).getPublicKey());
}
}
}
}
}
throw new KeySelectorException("No X509Certificate found!");
}
}
private static class SimpleKeySelectorResult implements KeySelectorResult {
private PublicKey pk;
SimpleKeySelectorResult(PublicKey pk) {
this.pk = pk;
}
public Key getKey() {
return pk;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment