Hello,
after further investigation i found out that the signature itself is valid but
the reference validation fails.
The signatures are created using JRE5 xmldsig and the SUN xmlsec APIs.
This is the actual code:
public void signDocumentXPath(Document document, PrivateKey privKey,
String baseXPath)
throws Exception {
// Create a DOM XMLSignatureFactory that will be used to generate the
// enveloped signature
String providerName = System.getProperty("jsr105Provider",
"org.jcp.xml.dsig.internal.dom.XMLDSigRI");
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
(Provider) Class.forName(providerName).newInstance());
// Create a Reference to the enveloped document (in this case we are
// signing the whole document, so a URI of "" signifies that) and
// also specify the SHA1 digest algorithm and the ENVELOPED Transform.
Vector v = new Vector();
XPathType type = new XPathType(baseXPath, XPathType.Filter.UNION);
v.add(type);
XPathFilter2ParameterSpec spec = new XPathFilter2ParameterSpec(v);
Reference ref = fac.newReference(
"", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList(
fac.newTransform(
Transform.XPATH2, (TransformParameterSpec) spec)), null,
null);
// Create the SignedInfo
SignedInfo si =
fac.newSignedInfo(
fac.newCanonicalizationMethod(
CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
(C14NMethodParameterSpec) null), fac.newSignatureMethod(
SignatureMethod.RSA_SHA1,
null), Collections.singletonList(ref));
// Create a KeyValue containing the RSA PublicKey that was generated
KeyInfoFactory kif = fac.getKeyInfoFactory();
//KeyValue kv = kif.newKeyValue(kp.getPublic());
KeyName kn = kif.newKeyName("My Keyname");
// Create a KeyInfo and add the KeyValue to it
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kn));
// Create a DOMSignContext and specify the DSA PrivateKey and
// location of the resulting XMLSignature's parent element
DOMSignContext dsc = new DOMSignContext(privKey,
document.getDocumentElement());
// Create the XMLSignature (but don't sign it yet)
XMLSignature signature = fac.newXMLSignature(si, ki);
// Marshal, generate (and sign) the enveloped signature
signature.sign(dsc);
}
(this is my xml doc created by the SUN XML API)
<?xml version="1.0" encoding="UTF-8"?><tbone>
<license>
<param name="myparam">Test</param>
</license>
<Signature
xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/><SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference
URI=""><Transforms><Transform
Algorithm="http://www.w3.org/2002/06/xmldsig-filter2"><XPath
xmlns="http://www.w3.org/2002/06/xmldsig-filter2"
Filter="union">/tbone/license</XPath></Transform></Transforms><DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>cp68+Em7EAO6X62j+kw7a8T08qU=</DigestValue></Reference></SignedInfo><SignatureValue>TH3tGkUs0Pnzgzb74OjVjqkrZA/9LqBaC4ZzrPrFevsdPBl94XFKg3hPdofLBdFkvb+vkYb9T9TT
0436m+aQOnC6Y9pwk7lCKYPvbPeZcwCwUCFa7ccGh0jGSyp83QgBI6eqomWkaI8xq56WjgcvXKiv
JvZ4sh7QsdQp3dw2q84=</SignatureValue><KeyInfo><KeyName>My
Keyname</KeyName></KeyInfo></Signature></tbone>
When i verify the created signature with Apache XML and enabled debugging i get
the following log outputs:
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.DOMSignatureMethod verify
FEIN: Signature provider:SunRsaSign version 1.5
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.DOMSignatureMethod verify
FEIN: verifying with key: Sun RSA public key, 1024 bits
modulus:
90423977268013193772672493202847721746573381377536653055997475685558693423657635618679640933512827048211696104270215394685726992656662856050800019998736714201782694955154594507516110929849902421860824852636310291332896187286679644658867737292920964731844144276040900126543154791203642895978715491940484467691
public exponent: 65537
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.ApacheCanonicalizer transform
FEIN: Created transform for algorithm:
http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.ApacheCanonicalizer transform
FEIN: isNodeSet() = true
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.DOMSignedInfo canonicalize
FEIN: Canonicalized SignedInfo:
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></CanonicalizationMethod><SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod><Reference
URI=""><Transforms><Transform
Algorithm="http://www.w3.org/2002/06/xmldsig-filter2"><XPath
xmlns="http://www.w3.org/2002/06/xmldsig-filter2"
Filter="union">/tbone/license</XPath></Transform></Transforms><DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod><DigestValue>cp68+Em7EAO6X62j+kw7a8T08qU=</DigestValue></Reference></SignedInfo>
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.DOMSignedInfo canonicalize
FEIN: Data to be
signed/verified:PFNpZ25lZEluZm8geG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPjxD
YW5vbmljYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvVFIvMjAw
MS9SRUMteG1sLWMxNG4tMjAwMTAzMTUjV2l0aENvbW1lbnRzIj48L0Nhbm9uaWNhbGl6YXRpb25N
ZXRob2Q+PFNpZ25hdHVyZU1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAv
MDkveG1sZHNpZyNyc2Etc2hhMSI+PC9TaWduYXR1cmVNZXRob2Q+PFJlZmVyZW5jZSBVUkk9IiI+
PFRyYW5zZm9ybXM+PFRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDIv
MDYveG1sZHNpZy1maWx0ZXIyIj48WFBhdGggeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDIv
MDYveG1sZHNpZy1maWx0ZXIyIiBGaWx0ZXI9InVuaW9uIj4vdGJvbmUvbGljZW5zZTwvWFBhdGg+
PC9UcmFuc2Zvcm0+PC9UcmFuc2Zvcm1zPjxEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8v
d3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSI+PC9EaWdlc3RNZXRob2Q+PERpZ2VzdFZh
bHVlPmNwNjgrRW03RUFPNlg2Mmora3c3YThUMDhxVT08L0RpZ2VzdFZhbHVlPjwvUmVmZXJlbmNl
PjwvU2lnbmVkSW5mbz4=
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.DOMReference dereference
FEIN: URIDereferencer class name:
org.jcp.xml.dsig.internal.dom.DOMURIDereferencer
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.DOMReference dereference
FEIN: Data class name: org.jcp.xml.dsig.internal.dom.ApacheNodeSetData
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.ApacheTransform transformIt
FEIN: Created transform for algorithm: http://www.w3.org/2002/06/xmldsig-filter2
28.01.2009 12:50:20 org.jcp.xml.dsig.internal.dom.ApacheTransform transformIt
FEIN: ApacheData = true
0 [main] INFO org.apache.xml.security.utils.CachedXPathFuncHereAPI -
Registering Here function
28.01.2009 12:50:21 org.jcp.xml.dsig.internal.DigesterOutputStream write
FEINER: Pre-digested input:
28.01.2009 12:50:21 org.jcp.xml.dsig.internal.DigesterOutputStream write
FEINER: <tbone>
<license>
<param name="myparam">Test</param>
</license>
<Signature
xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"></CanonicalizationMethod><SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod><Reference
URI=""><Transforms><Transform
Algorithm="http://www.w3.org/2002/06/xmldsig-filter2"><XPath
xmlns="http://www.w3.org/2002/06/xmldsig-filter2"
Filter="union">/tbone/license</XPath></Transform></Transforms><DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod><DigestValue>cp68+Em7EAO6X62j+kw7a8T08qU=</DigestValue></Reference></SignedInfo><SignatureValue>TH3tGkUs0Pnzgzb74OjVjqkrZA/9LqBaC4ZzrPrFevsdPBl94XFKg3hPdofLBdFkvb+vkYb9T9TT
0436m+aQOnC6Y9pwk7lCKYPvbPeZcwCwUCFa7ccGh0jGSyp83QgBI6eqomWkaI8xq56WjgcvXKiv
JvZ4sh7QsdQp3dw2q84=</SignatureValue><KeyInfo><KeyName>My
Keyname</KeyName></KeyInfo></Signature></tbone>
28.01.2009 12:50:21 org.jcp.xml.dsig.internal.dom.DOMReference validate
FEIN: Expected digest: cp68+Em7EAO6X62j+kw7a8T08qU=
28.01.2009 12:50:21 org.jcp.xml.dsig.internal.dom.DOMReference validate
FEIN: Actual digest: P1nwaETN2vl9o4U4FSRVdb6U0Sc=
28.01.2009 12:50:21 org.jcp.xml.dsig.internal.dom.DOMXMLSignature validate
FEIN: Reference[] is valid: false
28.01.2009 12:50:21 org.jcp.xml.dsig.internal.dom.DOMXMLSignature validate
FEIN: Couldn't validate the References
This forum post hinted at a possible namespace problem
http://forums.java.net/jive/message.jspa?messageID=37326
but im not sure - because i dont see the suggested 2 pre-digests output.
--- On Tue, 1/27/09, Sean Mullan <[email protected]> wrote:
> From: Sean Mullan <[email protected]>
> Subject: Re: Invalid Signature problem through Empty elements are converted
> to start-end tag pairs
> To: [email protected]
> Date: Tuesday, January 27, 2009, 2:49 PM
> Harakiri wrote:
> > We created signatures using the SUN XML Signature APIs
> in JRE 5 Versions.
>
> Hmm, which APIs are those? What software are you using?
> Have you tried JRE 6 to see if the problem still exists?
>
> > Due to a bug in SUNs API we like to use the XML
> Security API from Apache.
> >
> > However, all our signatures are invalid through
> possibly a bug in java.
> >
> > The signatures have been created with the following:
> >
> > http://www.w3.org/TR/2001/REC-xml-c14n-20010315
> >
> > however it seems that java signed empty tags as:
> >
> > <param name="myparam"/>
> >
> > but apache security correctly validates as
> >
> > <param name="myparam"></param>
> >
> > Since i cant just change existing signatures, how can
> I modify the apache xmldsig validation so that it will not
> compute the hash over the empty tags as
> <param></param> but as <param/> ?
>
> You can't, as Scott notes. Well, you could hack up the
> code yourself and build your own library but then you would
> just be bug-compatible. The existing signatures would still
> not interoperate with other vendors.
>
> Sorry, but I think your only solution may be to regenerate
> the signatures.
>
> --Sean