How do I implement XML Security in my XML app?
I had always thought of myself as a reasonably intelligent person. Now that I'm trying to learn how to implement XMLSignatures into my XML processing framework, I realize how ignorant I am!
I downloaded the XML security packages from apache and after two days of trial-and-error, I have keystores set up and I can create XMLSignatures and sign XML documents I create with DOM.
But when I try and validate the signature on the other end (after I've created another XMLSignature object from the XML I recieved) with the certificate I've exported from the client keystore, it fails every time.
I've exported the server and client certificates and imported them into the other's keystores (i.e. the server trusts the client's certificate and vice versa) and if I call X509Certificate.equals(CertificateFromMyXML) it says "true". But if I try and validate the XMLSignatures, it returns false. How can it not validate the XMLSignatures if it knows that the certificate from the keystore exactly matches the one I just got in my XML.
I'm hopelessly confused. Can someone point me in the right direction so that I'm not spining my wheels, staring at my screen, wondering what the heck I have to do to understand this stuff!?
Any documentation or pointers you can direct me to would be extremely helpful.
Thanks!
Jon Brisbin
Webmaster
NPC International, Inc.
Here's the sample program I'm using:
public static void main( String[] args ) throws Exception
{
KeyStore ks = KeyStore.getInstance( KeyStore.getDefaultType() );
ks.load( Authenticator.class.getResourceAsStream( "/qnpc.jks" ),
"****".toCharArray() );
X509Certificate cert = (X509Certificate) ks
.getCertificate( "webservice" );
StringWriter sw = new StringWriter();
OutputFormat of = new OutputFormat();
of.setIndenting( true );
of.setIndent( 2 );
of.setLineWidth( 80 );
XMLSerializer ser = new XMLSerializer( sw, of );
Document doc = makeDoc();
org.w3c.dom.Element el = doc.getDocumentElement();
XMLSignature xSig = new XMLSignature( doc, NS,
XMLSignature.ALGO_ID_SIGNATURE_DSA );
// Transforms transforms = new Transforms( doc );
// transforms.addTransform( Transforms.TRANSFORM_ENVELOPED_SIGNATURE );
// xSig.addDocument( "", transforms, Constants.ALGO_ID_DIGEST_SHA1 );
xSig.addDocument( "" );
xSig.addKeyInfo( cert );
el.appendChild( xSig.getElement() );
xSig.sign( ks.getKey( "webservice", "****".toCharArray() ) );
ser.serialize( doc );
System.out.println( sw.toString() );
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware( true );
dbf.setAttribute( "http://xml.org/sax/features/namespaces",
Boolean.TRUE );
DocumentBuilder db = dbf.newDocumentBuilder();
KeyStore ks2 = KeyStore.getInstance( KeyStore.getDefaultType() );
ks2.load( Authenticator.class.getResourceAsStream( "/xportal.jks" ),
"lassie57".toCharArray() );
Document doc2 = db.parse( new ByteArrayInputStream( sw.toString()
.getBytes() ) );
org.w3c.dom.Element sig = (org.w3c.dom.Element) doc2
.getElementsByTagNameNS( Constants.SignatureSpecNS, "Signature" )
.item( 0 );
XMLSignature xSig2 = new XMLSignature( sig, "" );
X509Certificate cert2 = xSig2.getKeyInfo().getX509Certificate();
X509Certificate clientCert = (X509Certificate) ks2
.getCertificate( "qnpc" );
sw = new StringWriter();
ser = new XMLSerializer( sw, of );
ser.serialize( xSig2.getElement() );
System.out.println( sw.toString() );
KeyUtils.prinoutKeyInfo( xSig2.getKeyInfo(), System.out );
System.out.println( sw.toString() );
System.out.println( "Signed by QNPC?: " + cert2.equals( clientCert ) );
System.out.println( "Valid?: " + xSig2.checkSignatureValue( cert2 ) );
}