Avatar
mc
Člen
Avatar
mc:

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.cryp­to.*). 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.cryp­to.dsig.XMLSig­natureExcepti­on: javax.xml.cryp­to.URIReferen­ceException: com.sun.org.a­pache.xml.inter­nal.security.u­tils.resolver­.ResourceResol­verException: 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?

public void podepisZpravu(SOAPMessageContext smc) throws Exception {

                //vytvoří novou zprávu která se má podepsat
                vytvorZpravu(smc);

                SOAPMessage zprava = smc.getMessage();

                //udaje o klicich
                final 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")));
 
Odpovědět 16.9.2013 14:45
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.

Zobrazeno 1 zpráv z 1.