Zdravím, nemáte tu někdo zkušenosti s podepisováním XML? Potřebuju do
hlavičky SOAP požadavku přidat podpis dokumentu. Momentálně to řeším
pomocí Java XML Digital Signature API (z namespace javax.xml.crypto.*). Pokud
znáte někdo lepší variantu tak ji můžete zmínit
Aktuálně řeším problém s referencemi v dokumentu. V dokumentu mám 2
elementy na které se chci odkázat pomocí reference ale bohužel při
derefenrci dojde k vyjimce: javax.xml.crypto.dsig.XMLSignatureException:
javax.xml.crypto.URIReferenceException:
com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException:
Cannot resolve element with ID Id-34667487
Kompletní log: (http://pastebin.com/M1HxcUPT). Vážně už si nevím rady.
Chápu že nemůže najít ty referované elementy ale nechápu proč. Nějaké
rady?
publicvoid podepisZpravu(SOAPMessageContext smc) throws Exception {
//vytvoří novou zprávu která se má podepsat
vytvorZpravu(smc);
SOAPMessage zprava = smc.getMessage();
//udaje o klicichfinal String cestaKCertifikatu = "<cestaKCertifikatu>";
final String hesloKCertifikatu = "<heslo>";
final String aliasCertifikatu = "le-954aeced-9356-4c6e-8b8b-975bcc7deed9";
//načte klíč do klíčenky
KeyStore klicenka = KeyStore.getInstance("pkcs12");
char[] heslo = hesloKCertifikatu.toCharArray();
FileInputStream streamCertifikatu = new FileInputStream(cestaKCertifikatu);
klicenka.load(streamCertifikatu, heslo);
//vytvoří proměnné s certifikátem a klíčem
X509Certificate certifikat = (X509Certificate) klicenka.getCertificate(aliasCertifikatu);
Key podepisovaciKlic = klicenka.getKey(aliasCertifikatu, heslo);
//vytvoří dokument k podepsání
Document dokument = vytvorDokument(zprava);
//vytvoření továrničky jež je základní třídou pro XML podpis
XMLSignatureFactory podpisTovarna = XMLSignatureFactory.getInstance("DOM");
KeyInfoFactory kif = podpisTovarna.getKeyInfoFactory();
//seznam potomků keyInfo v XML
List<XMLStructure> keyInfoList = new ArrayList<XMLStructure>();
//
KeyValue keyValue = kif.newKeyValue(certifikat.getPublicKey());
keyInfoList.add(keyValue);
//List x509dataList = new ArrayList();//X509IssuerSerial issuerSerial =// kif.newX509IssuerSerial(certifikat.getIssuerX500Principal().getName(),// certifikat.getSerialNumber());//x509dataList.add(issuerSerial);//x509dataList.add(certifikat.getSubjectX500Principal().getName());//x509dataList.add(certifikat);//keyInfoList.add(kif.newX509Data(x509dataList));
KeyInfo keyInfo = kif.newKeyInfo(keyInfoList);
//vytvořená kanonizační metoda, slouží k úpravě xml dokumentu//umožnuje odstranit některé znaky při zachování stejného významu xml dokumentu
CanonicalizationMethod kanonizacniMetoda =
podpisTovarna.newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE,
(C14NMethodParameterSpec) null);
//metoda sloužící k samotnému podepisování
SignatureMethod podepisovaciMetoda =
podpisTovarna.newSignatureMethod(SignatureMethod.RSA_SHA1,null);
//metoda vytvoření otisku daného elementu (otisk ==? hash)
DigestMethod digestMetoda =
podpisTovarna.newDigestMethod(DigestMethod.SHA1, null);
//vytvoření referencí na části dokumentu
Reference referenceTelo =
podpisTovarna.newReference("#" + teloZpravyId, digestMetoda);
Reference referenceCasovaZnacka =
podpisTovarna.newReference("#" + casovaZnackaId, digestMetoda);
//konstrukce seznamu referencí
List<Reference> seznamReferenci = new ArrayList<>();
seznamReferenci.add(referenceTelo);
seznamReferenci.add(referenceCasovaZnacka);
//informace o podpisu
SignedInfo informaceOPodpisu =
podpisTovarna.newSignedInfo(kanonizacniMetoda, podepisovaciMetoda,
seznamReferenci);
//objekt pro podpis
XMLSignature podpis = podpisTovarna.newXMLSignature(informaceOPodpisu, keyInfo);
//
DOMSignContext podepisovaciKontext = new DOMSignContext(podepisovaciKlic, dokument.getDocumentElement());
//
podepisovaciKontext.putNamespacePrefix(XMLSignature.XMLNS, "ds");
podpis.sign(podepisovaciKontext);
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
final Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(dokument), new StreamResult(
new FileOutputStream("M:\\test_podepsany.xml")));
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.