libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 9118044da78bddbf715a2448edc68beda009ca7e
parent e22d477d5bc076fecec9d732b04cedb59b33a5f2
Author: Florian Dold <florian.dold@gmail.com>
Date:   Mon,  4 Nov 2019 09:13:45 +0100

XML signatures

Diffstat:
Rnexus/src/resources/logback.xml -> nexus/src/main/resources/logback.xml | 0
Msandbox/src/main/kotlin/DB.kt | 5+++++
Msandbox/src/main/kotlin/Main.kt | 59+++++++++++++++++++++++++++++++++++++++++++++++++----------
Msandbox/src/main/kotlin/XMLUtil.kt | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt | 43+++++++++++++++++++++++++++++++++++++++++++
Rsandbox/src/resources/logback.xml -> sandbox/src/main/resources/logback.xml | 0
Rsandbox/src/main/resources/ebics_H004.xsd -> sandbox/src/main/resources/xsd/ebics_H004.xsd | 0
Rsandbox/src/main/resources/ebics_hev.xsd -> sandbox/src/main/resources/xsd/ebics_hev.xsd | 0
Rsandbox/src/main/resources/ebics_keymgmt_request_H004.xsd -> sandbox/src/main/resources/xsd/ebics_keymgmt_request_H004.xsd | 0
Rsandbox/src/main/resources/ebics_keymgmt_response_H004.xsd -> sandbox/src/main/resources/xsd/ebics_keymgmt_response_H004.xsd | 0
Rsandbox/src/main/resources/ebics_orders_H004.xsd -> sandbox/src/main/resources/xsd/ebics_orders_H004.xsd | 0
Rsandbox/src/main/resources/ebics_request_H004.xsd -> sandbox/src/main/resources/xsd/ebics_request_H004.xsd | 0
Rsandbox/src/main/resources/ebics_response_H004.xsd -> sandbox/src/main/resources/xsd/ebics_response_H004.xsd | 0
Rsandbox/src/main/resources/ebics_signature_S002.xsd -> sandbox/src/main/resources/xsd/ebics_signature_S002.xsd | 0
Rsandbox/src/main/resources/ebics_signatures.xsd -> sandbox/src/main/resources/xsd/ebics_signatures.xsd | 0
Rsandbox/src/main/resources/ebics_types_H004.xsd -> sandbox/src/main/resources/xsd/ebics_types_H004.xsd | 0
Rsandbox/src/main/resources/xmldsig-core-schema.xsd -> sandbox/src/main/resources/xsd/xmldsig-core-schema.xsd | 0
Msandbox/src/test/kotlin/EbicsMessagesTest.kt | 24+++++++++++++++---------
Msandbox/src/test/kotlin/XmlUtilTest.kt | 26++++++++++++++++----------
Asandbox/src/test/resources/signature1/doc.xml | 9+++++++++
Asandbox/src/test/resources/signature1/public_key.txt | 2++
21 files changed, 202 insertions(+), 45 deletions(-)

diff --git a/nexus/src/resources/logback.xml b/nexus/src/main/resources/logback.xml diff --git a/sandbox/src/main/kotlin/DB.kt b/sandbox/src/main/kotlin/DB.kt @@ -22,6 +22,7 @@ package tech.libeufin.sandbox.db import org.jetbrains.exposed.dao.* import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.transactions.transaction +import java.sql.Blob const val CUSTOMER_NAME_MAX_LENGTH = 20 const val EBICS_HOST_ID_MAX_LENGTH = 10 @@ -81,6 +82,10 @@ enum class KeyState { RELEASED } +fun Blob.toByteArray(): ByteArray { + return this.binaryStream.readAllBytes() +} + /** * This table information *not* related to EBICS, for all * its customers. diff --git a/sandbox/src/main/kotlin/Main.kt b/sandbox/src/main/kotlin/Main.kt @@ -46,6 +46,7 @@ import org.slf4j.LoggerFactory import org.w3c.dom.Document import tech.libeufin.sandbox.db.* import tech.libeufin.schema.ebics_h004.EbicsKeyManagementResponse +import tech.libeufin.schema.ebics_h004.EbicsNoPubKeyDigestsRequest import tech.libeufin.schema.ebics_h004.EbicsUnsecuredRequest import tech.libeufin.schema.ebics_h004.HIARequestOrderDataType import tech.libeufin.schema.ebics_hev.HEVResponse @@ -68,8 +69,8 @@ private suspend fun ApplicationCall.respondEbicsKeyManagement( errorText: String, errorCode: String, statusCode: HttpStatusCode, - orderId: String? = null, - bankReturnCode: String? = null + bankReturnCode: String, + orderId: String? = null ) { val responseXml = EbicsKeyManagementResponse().apply { version = "H004" @@ -85,11 +86,9 @@ private suspend fun ApplicationCall.respondEbicsKeyManagement( _static = EbicsKeyManagementResponse.Header.EmptyStaticHeader() } body = EbicsKeyManagementResponse.Body().apply { - if (bankReturnCode != null) { - this.returnCode = EbicsKeyManagementResponse.Body.ReturnCode().apply { - this.authenticate = true - this.value = bankReturnCode - } + this.returnCode = EbicsKeyManagementResponse.Body.ReturnCode().apply { + this.authenticate = true + this.value = bankReturnCode } } } @@ -100,7 +99,7 @@ private suspend fun ApplicationCall.respondEbicsKeyManagement( private suspend fun ApplicationCall.respondEbicsInvalidXml() { - respondEbicsKeyManagement("[EBICS_INVALID_XML]", "091010", HttpStatusCode.BadRequest) + respondEbicsKeyManagement("[EBICS_INVALID_XML]", "091010", HttpStatusCode.BadRequest, "000000") } @@ -118,6 +117,12 @@ fun findEbicsSubscriber(partnerID: String, userID: String, systemID: String?): E }.firstOrNull() } +data class SubscriberKeys( + val authenticationPublicKey: RSAPublicKey, + val encryptionPublicKey: RSAPublicKey, + val signaturePublicKey: RSAPublicKey +) + private suspend fun ApplicationCall.ebicsweb() { val body: String = receiveText() logger.debug("Data received: $body") @@ -148,7 +153,7 @@ private suspend fun ApplicationCall.ebicsweb() { if (ebicsHost == null) { logger.warn("client requested unknown HostID") - respondEbicsKeyManagement("[EBICS_INVALID_HOST_ID]", "091011", HttpStatusCode.NotFound) + respondEbicsKeyManagement("[EBICS_INVALID_HOST_ID]", "091011", HttpStatusCode.NotFound, "000000") return } @@ -294,7 +299,8 @@ private suspend fun ApplicationCall.ebicsweb() { ebicsSubscriber.state = SubscriberState.INITIALIZED } } - respondEbicsKeyManagement("[EBICS_OK]", "000000", HttpStatusCode.OK) + respondEbicsKeyManagement("[EBICS_OK]", "000000", HttpStatusCode.OK, "000000") + return } } @@ -314,6 +320,39 @@ private suspend fun ApplicationCall.ebicsweb() { respondText(strResp, ContentType.Application.Xml, HttpStatusCode.OK) return } + "ebicsNoPubKeyDigestsRequest" -> { + val requestJaxb = XMLUtil.convertDomToJaxb(EbicsNoPubKeyDigestsRequest::class.java, bodyDocument) + val staticHeader = requestJaxb.value.header.static + val orderType = staticHeader.orderDetails.orderType + when (orderType) { + "HPB" -> { + val subscriberKeys = transaction { + val ebicsSubscriber = + findEbicsSubscriber(staticHeader.partnerID, staticHeader.userID, staticHeader.systemID) + if (ebicsSubscriber == null) { + throw EbicsRequestError(HttpStatusCode.Unauthorized) + } + if (ebicsSubscriber.state != SubscriberState.INITIALIZED) { + throw EbicsRequestError(HttpStatusCode.Forbidden) + } + val authPubBlob = ebicsSubscriber.authenticationKey!!.rsaPublicKey + val encPubBlob = ebicsSubscriber.encryptionKey!!.rsaPublicKey + val sigPubBlob = ebicsSubscriber.signatureKey!!.rsaPublicKey + SubscriberKeys( + CryptoUtil.loadRsaPublicKey(authPubBlob.toByteArray()), + CryptoUtil.loadRsaPublicKey(encPubBlob.toByteArray()), + CryptoUtil.loadRsaPublicKey(sigPubBlob.toByteArray()) + ) + } + val validationResult = XMLUtil.verifyEbicsDocument(bodyDocument, subscriberKeys.authenticationPublicKey) + logger.info("validationResult: $validationResult") + } + else -> { + logger.warn("order type '${orderType}' not supported for ebicsNoPubKeyDigestsRequest") + respondEbicsInvalidXml() + } + } + } else -> { /* Log to console and return "unknown type" */ logger.info("Unknown message, just logging it!") diff --git a/sandbox/src/main/kotlin/XMLUtil.kt b/sandbox/src/main/kotlin/XMLUtil.kt @@ -20,6 +20,7 @@ package tech.libeufin.sandbox import com.sun.org.apache.xerces.internal.dom.DOMInputImpl +import org.apache.xml.security.c14n.Canonicalizer import org.w3c.dom.Document import org.w3c.dom.Node import org.w3c.dom.NodeList @@ -30,6 +31,8 @@ import org.xml.sax.InputSource import org.xml.sax.SAXException import org.xml.sax.SAXParseException import java.io.* +import java.lang.UnsupportedOperationException +import java.security.MessageDigest import java.security.PrivateKey import java.security.PublicKey import java.util.* @@ -44,6 +47,7 @@ import javax.xml.crypto.dsig.dom.DOMSignContext import javax.xml.crypto.dsig.dom.DOMValidateContext import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec import javax.xml.crypto.dsig.spec.TransformParameterSpec +import javax.xml.namespace.NamespaceContext import javax.xml.parsers.DocumentBuilderFactory import javax.xml.transform.OutputKeys import javax.xml.transform.Source @@ -78,11 +82,18 @@ class XMLUtil { if (nodeSet.length <= 0) { throw Exception("no nodes to sign") } - val nodeList = LinkedList<Node>() + val bytes = ByteArrayOutputStream() for (i in 0 until nodeSet.length) { - nodeList.add(nodeSet.item(i)) + val node = nodeSet.item(i) + org.apache.xml.security.Init.init() + // Despite the transform later, this canonicalization step is absolutely necessary, + // as the canonicalizeSubtree method preserves namespaces that are not in the subtree + // being canonicalized, but in the parent hierarchy of the document. + val canon: Canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS) + val cxml = canon.canonicalizeSubtree(node) + bytes.writeBytes(cxml) } - return NodeSetData { nodeList.iterator() } + return OctetStreamData(ByteArrayInputStream(bytes.toByteArray())) } } @@ -119,11 +130,11 @@ class XMLUtil { if (type != "http://www.w3.org/2001/XMLSchema") { return null } - val res = classLoader.getResourceAsStream(systemId) ?: return null + val res = classLoader.getResourceAsStream("xsd/$systemId") ?: return null return DOMInputImpl(publicId, systemId, baseUri, res, "UTF-8") } } - val schemaInputs: Array<Source> = listOf("ebics_H004.xsd", "ebics_hev.xsd").map { + val schemaInputs: Array<Source> = listOf("xsd/ebics_H004.xsd", "xsd/ebics_hev.xsd").map { val resUrl = classLoader.getResource(it) ?: throw FileNotFoundException("Schema file $it not found.") StreamSource(File(resUrl.toURI())) }.toTypedArray() @@ -207,12 +218,12 @@ class XMLUtil { * @param document the DOM to extract the string from. * @return the final String, or null if errors occur. */ - fun convertDomToString(document: Document): String? { + fun convertDomToString(document: Document): String { /* Make Transformer. */ val tf = TransformerFactory.newInstance() val t = tf.newTransformer() - t.setOutputProperty(OutputKeys.INDENT, "yes") + //t.setOutputProperty(OutputKeys.INDENT, "yes") /* Make string writer. */ val sw = StringWriter() @@ -222,12 +233,16 @@ class XMLUtil { return sw.toString() } - fun convertNodeToString(node: Node): String? { + /** + * Convert a node to a string without the XML declaration or + * indentation. + */ + fun convertNodeToString(node: Node): String { /* Make Transformer. */ val tf = TransformerFactory.newInstance() val t = tf.newTransformer() - t.setOutputProperty(OutputKeys.INDENT, "yes") + t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); /* Make string writer. */ val sw = StringWriter() @@ -273,7 +288,23 @@ class XMLUtil { */ fun signEbicsDocument(doc: Document, signingPriv: PrivateKey): Unit { val xpath = XPathFactory.newInstance().newXPath() - val authSigNode = xpath.compile("/*[1]/AuthSignature").evaluate(doc, XPathConstants.NODE) + xpath.namespaceContext = object : NamespaceContext { + override fun getNamespaceURI(p0: String?): String { + return when (p0) { + "ebics" -> "urn:org:ebics:H004" + else -> throw IllegalArgumentException() + } + } + + override fun getPrefix(p0: String?): String { + throw UnsupportedOperationException() + } + + override fun getPrefixes(p0: String?): MutableIterator<String> { + throw UnsupportedOperationException() + } + } + val authSigNode = xpath.compile("/*[1]/ebics:AuthSignature").evaluate(doc, XPathConstants.NODE) if (authSigNode !is Node) throw java.lang.Exception("no AuthSignature") val fac = XMLSignatureFactory.getInstance("DOM") @@ -306,8 +337,24 @@ class XMLUtil { fun verifyEbicsDocument(doc: Document, signingPub: PublicKey): Boolean { val xpath = XPathFactory.newInstance().newXPath() + xpath.namespaceContext = object : NamespaceContext { + override fun getNamespaceURI(p0: String?): String { + return when (p0) { + "ebics" -> "urn:org:ebics:H004" + else -> throw IllegalArgumentException() + } + } + + override fun getPrefix(p0: String?): String { + throw UnsupportedOperationException() + } + + override fun getPrefixes(p0: String?): MutableIterator<String> { + throw UnsupportedOperationException() + } + } val doc2: Document = doc.cloneNode(true) as Document - val authSigNode = xpath.compile("/*[1]/AuthSignature").evaluate(doc2, XPathConstants.NODE) + val authSigNode = xpath.compile("/*[1]/ebics:AuthSignature").evaluate(doc2, XPathConstants.NODE) if (authSigNode !is Node) throw java.lang.Exception("no AuthSignature") val sigEl = doc2.createElementNS("http://www.w3.org/2000/09/xmldsig#", "ds:Signature") @@ -317,12 +364,13 @@ class XMLUtil { } authSigNode.parentNode.removeChild(authSigNode) val fac = XMLSignatureFactory.getInstance("DOM") - println(convertDomToString(doc2)) val dvc = DOMValidateContext(signingPub, sigEl) dvc.uriDereferencer = EbicsSigUriDereferencer() val sig = fac.unmarshalXMLSignature(dvc) - // FIXME: check that parameters are okay! - return sig.validate(dvc) + // FIXME: check that parameters are okay!s + val valResult = sig.validate(dvc) + sig.signedInfo.references[0].validate(dvc) + return valResult } } -} -\ No newline at end of file +} diff --git a/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt b/sandbox/src/main/kotlin/tech/libeufin/schema/ebics_h004/EbicsMessages.kt @@ -540,3 +540,45 @@ class EbicsKeyManagementResponse { } } } + + +@XmlAccessorType(XmlAccessType.NONE) +@XmlType(name = "", propOrder = ["header", "authSignature", "body"]) +@XmlRootElement(name = "ebicsNoPubKeyDigestsRequest") +class EbicsNoPubKeyDigestsRequest { + @get:XmlAttribute(name = "Version", required = true) + @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) + lateinit var version: String + + @get:XmlAttribute(name = "Revision") + var revision: Int? = null + + @get:XmlElement(name = "header", required = true) + lateinit var header: Header + + @get:XmlElement(name = "AuthSignature", required = true) + lateinit var authSignature: SignatureType + + @get:XmlElement(required = true) + lateinit var body: EmptyBody + + @XmlAccessorType(XmlAccessType.NONE) + @XmlType(name = "", propOrder = ["static", "mutable"]) + class Header { + @get:XmlAttribute(name = "authenticate", required = true) + var authenticate: Boolean = false + + @get:XmlElement(name = "static", required = true) + lateinit var static: StaticHeader + + @get:XmlElement(required = true) + lateinit var mutable: EmptyMutableHeader + + @XmlAccessorType(XmlAccessType.NONE) + @XmlType(name = "") + class EmptyMutableHeader + } + + @XmlAccessorType(XmlAccessType.NONE) + class EmptyBody +} +\ No newline at end of file diff --git a/sandbox/src/resources/logback.xml b/sandbox/src/main/resources/logback.xml diff --git a/sandbox/src/main/resources/ebics_H004.xsd b/sandbox/src/main/resources/xsd/ebics_H004.xsd diff --git a/sandbox/src/main/resources/ebics_hev.xsd b/sandbox/src/main/resources/xsd/ebics_hev.xsd diff --git a/sandbox/src/main/resources/ebics_keymgmt_request_H004.xsd b/sandbox/src/main/resources/xsd/ebics_keymgmt_request_H004.xsd diff --git a/sandbox/src/main/resources/ebics_keymgmt_response_H004.xsd b/sandbox/src/main/resources/xsd/ebics_keymgmt_response_H004.xsd diff --git a/sandbox/src/main/resources/ebics_orders_H004.xsd b/sandbox/src/main/resources/xsd/ebics_orders_H004.xsd diff --git a/sandbox/src/main/resources/ebics_request_H004.xsd b/sandbox/src/main/resources/xsd/ebics_request_H004.xsd diff --git a/sandbox/src/main/resources/ebics_response_H004.xsd b/sandbox/src/main/resources/xsd/ebics_response_H004.xsd diff --git a/sandbox/src/main/resources/ebics_signature_S002.xsd b/sandbox/src/main/resources/xsd/ebics_signature_S002.xsd diff --git a/sandbox/src/main/resources/ebics_signatures.xsd b/sandbox/src/main/resources/xsd/ebics_signatures.xsd diff --git a/sandbox/src/main/resources/ebics_types_H004.xsd b/sandbox/src/main/resources/xsd/ebics_types_H004.xsd diff --git a/sandbox/src/main/resources/xmldsig-core-schema.xsd b/sandbox/src/main/resources/xsd/xmldsig-core-schema.xsd diff --git a/sandbox/src/test/kotlin/EbicsMessagesTest.kt b/sandbox/src/test/kotlin/EbicsMessagesTest.kt @@ -18,7 +18,7 @@ class EbicsMessagesTest { * messages. */ @Test - fun importNonRoot() { + fun testImportNonRoot() { val classLoader = ClassLoader.getSystemClassLoader() val ini = classLoader.getResource("ebics_ini_inner_key.xml") val jaxb = XMLUtil.convertStringToJaxb<SignaturePubKeyOrderData>(ini.readText()) @@ -29,7 +29,7 @@ class EbicsMessagesTest { * Test string -> JAXB */ @Test - fun stringToJaxb() { + fun testStringToJaxb() { val classLoader = ClassLoader.getSystemClassLoader() val ini = classLoader.getResource("ebics_ini_request_sample.xml") val jaxb = XMLUtil.convertStringToJaxb<EbicsUnsecuredRequest>(ini.readText()) @@ -44,7 +44,7 @@ class EbicsMessagesTest { * Test JAXB -> string */ @Test - fun jaxbToString() { + fun testJaxbToString() { val hevResponseJaxb = HEVResponse().apply { this.systemReturnCode = SystemReturnCodeType().apply { this.reportText = "[EBICS_OK]" @@ -55,12 +55,11 @@ class EbicsMessagesTest { XMLUtil.convertJaxbToString(hevResponseJaxb) } - /** * Test DOM -> JAXB */ @Test - fun domToJaxb() { + fun testDomToJaxb() { val classLoader = ClassLoader.getSystemClassLoader() val ini = classLoader.getResource("ebics_ini_request_sample.xml")!! val iniDom = XMLUtil.parseStringIntoDom(ini.readText()) @@ -100,7 +99,7 @@ class EbicsMessagesTest { } @Test - fun hiaLoad() { + fun testHiaLoad() { val classLoader = ClassLoader.getSystemClassLoader() val hia = classLoader.getResource("hia_request.xml")!! val hiaDom = XMLUtil.parseStringIntoDom(hia.readText()) @@ -122,7 +121,7 @@ class EbicsMessagesTest { } @Test - fun loadInnerKey() { + fun testLoadInnerKey() { val jaxbKey = run { val classLoader = ClassLoader.getSystemClassLoader() val file = classLoader.getResource( @@ -138,14 +137,14 @@ class EbicsMessagesTest { } @Test - fun loadIniMessage() { + fun testLoadIniMessage() { val classLoader = ClassLoader.getSystemClassLoader() val text = classLoader.getResource("ebics_ini_request_sample.xml")!!.readText() XMLUtil.convertStringToJaxb<EbicsUnsecuredRequest>(text) } @Test - fun loadResponse() { + fun testLoadResponse() { val response = EbicsResponse().apply { version = "H004" header = EbicsResponse.Header().apply { @@ -166,4 +165,11 @@ class EbicsMessagesTest { } print(XMLUtil.convertJaxbToString(response)) } + + @Test + fun testLoadHpb() { + val classLoader = ClassLoader.getSystemClassLoader() + val text = classLoader.getResource("hpb_request.xml")!!.readText() + XMLUtil.convertStringToJaxb<EbicsNoPubKeyDigestsRequest>(text) + } } \ No newline at end of file diff --git a/sandbox/src/test/kotlin/XmlUtilTest.kt b/sandbox/src/test/kotlin/XmlUtilTest.kt @@ -3,6 +3,7 @@ package tech.libeufin.sandbox import org.junit.Test import org.junit.Assert.* import java.security.KeyPairGenerator +import java.util.* import javax.xml.transform.stream.StreamSource class XmlUtilTest { @@ -26,23 +27,28 @@ class XmlUtilTest { @Test fun basicSigningTest() { val doc = XMLUtil.parseStringIntoDom(""" - <foo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> - <AuthSignature /> - <bar authenticate='true'>bla</bar>Hello World - <spam> - eggs - - ham - </spam> - </foo> + <myMessage xmlns:ebics="urn:org:ebics:H004"> + <ebics:AuthSignature /> + <foo authenticate="true">Hello World</foo> + </myMessage> """.trimIndent()) val kpg = KeyPairGenerator.getInstance("RSA") kpg.initialize(2048) val pair = kpg.genKeyPair() val otherPair = kpg.genKeyPair() XMLUtil.signEbicsDocument(doc, pair.private) - println(XMLUtil.convertDomToString(doc)) kotlin.test.assertTrue(XMLUtil.verifyEbicsDocument(doc, pair.public)) kotlin.test.assertFalse(XMLUtil.verifyEbicsDocument(doc, otherPair.public)) } + + @Test + fun testRefSignature() { + val classLoader = ClassLoader.getSystemClassLoader() + val docText = classLoader.getResourceAsStream("signature1/doc.xml")!!.readAllBytes().toString(Charsets.UTF_8) + val doc = XMLUtil.parseStringIntoDom(docText) + val keyText = classLoader.getResourceAsStream("signature1/public_key.txt")!!.readAllBytes() + val keyBytes = Base64.getDecoder().decode(keyText) + val key = CryptoUtil.loadRsaPublicKey(keyBytes) + assertTrue(XMLUtil.verifyEbicsDocument(doc, key)) + } } \ No newline at end of file diff --git a/sandbox/src/test/resources/signature1/doc.xml b/sandbox/src/test/resources/signature1/doc.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?><myMessage xmlns:ebics="urn:org:ebics:H004"> + <ebics:AuthSignature><ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#xpointer(//*[@authenticate='true'])"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>qiFUoCn9kE0zSidyraO2Br/wn3/XyvWObJZ0aLIBXyA=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">LupLyRUJIuk0kCRwpFj4fpen2MI7Jw0BI944agwzXHfSDfq0Pp8h3sub6eSsKIAq7ekT3z+mlfMc&#13; + VFaKRi4B7kv4ja/URiYCKKbChQU2+kMGDvsncx9VcpcFrqAbWPmE9JXD2W2YW9OSkJ1tAZxZlZwS&#13; + A8KcvluV1wGEBuakHL2t3GqFPQEfKW4l8GYTjHh/w9jBve5d8tvMOjGtoyNemZGrVlzBxO9+hwbw&#13; + 8UFUCDA00dCjFDUHOnyAbBYsGzoaQyZprDn3iYDvlBz243zAN98PIKDclxlUEmkuF+JhrhCRjT9l&#13; + +JJxrELGHaDkFVadR4kaPdWPsbDaV0/2Fzc4Qg==</ds:SignatureValue></ebics:AuthSignature> + <foo authenticate="true">Hello World</foo> +</myMessage> +\ No newline at end of file diff --git a/sandbox/src/test/resources/signature1/public_key.txt b/sandbox/src/test/resources/signature1/public_key.txt @@ -0,0 +1 @@ +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqpUpetHZYdMjnaG544iSLZ5SnxlV4F/eQsIckG3mvMaXCQsY4rUTfJyle/fTZ0xGbjCUXCsbl1wkz8eB6chaX2LsHYDGiu/xNnU1nddAVB+5kkA5AIGncT9NVhdOgmpnZY/tae9qtZfCPAvbI0sGYQHea0pwyJ/hUnRJiMOjSRgIXALIvGVNqxe4U5ffLXFIUapTK2hOuhUH9BwDSK+mVR6gw0vDT05Z38sEpTeKUqJywL5cPSFIV+AN4ErSvsXNkTKUcbDxhGzOh/oTjTkz1kFFKe4ijPkSRkpK2sJMyAIretBKOK8SDICnsSrIh0YAcd6yTHQ3CeEjW4t0ZBULOQIDAQAB +\ No newline at end of file