Hi, I resend this mail.
In fact, I signed SOAP message.
The development environment is : Axis and WebSphere 4.
I have develop from the axis sample of signature a signature mechanism
which runs.
But, I want to avoid deserialize or serialize the SOAP enveloppe as Axis
sample.
I use this code :
import java.io.InputStream;
import java.security.KeyStore;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.handlers.BasicHandler;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.message.SOAPHeaderElement;
import org.apache.xml.security.Init;
import org.apache.xml.security.signature.XMLSignature;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class SigningHandler extends BasicHandler {
static {org.apache.xml.security.Init.init(); }
/**
* @see BasicHandler#invoke(MessageContext)
*/
public void invoke(MessageContext arg0) throws AxisFault
{
try
{
SOAPEnvelope soapEnv = arg0.getCurrentMessage
().getSOAPEnvelope();
// Get SOAP Body as Document
Node body = soapEnv.getAsDocument().getElementsByTagNameNS
("http://schemas.xmlsoap.org/soap/envelope/","Body").item(0);
Document docBody = builder.newDocument();
docBody.appendChild(body);
Document document_SOAPENV = soapEnv.getAsDocument();
// Get Private Key and Certificate
java.security.KeyStore jks =
java.security.KeyStore.getInstance("JKS");
java.io.InputStream in = this.getClass().getResourceAsStream
("/../../keystore.jks");
jks.load(in, "xmlsecurity".toCharArray());
java.security.PrivateKey pk = (java.security.PrivateKey)
jks.getKey("test","xmlsecurity".toCharArray());
java.security.cert.X509Certificate cert
= (java.security.cert.X509Certificate) jks.getCertificate("test");
//Sign the SOAP Body
XMLSignature xmlSign = new
XMLSignature(document_SOAPENV,"http://xml-security",XMLSignature.ALGO_ID_SIGNATURE_DSA);
xmlSign.addDocument("#Body");
xmlSign.addKeyInfo(cert);
xmlSign.addKeyInfo(cert.getPublicKey());
xmlSign.sign(pk);
// INSERT Signature Element in the SOAP Header
Element elementXML = null;
Document doc = builder.newDocument();
Element elementXML = document_SOAPENV.createElementNS
("http://schemas.xmlsoap.org/ws/2002/04/secxt","Security");
elementXML.appendChild(xmlSign.getElement());
// Update the Message Context with the SOAP enveloppe
SOAPHeaderElement elmt = new SOAPHeaderElement(elementXML);
soapEnv.addHeader(elmt);
Message m = new Message(soapEnv);
arg0.setCurrentMessage(m);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
But if the "same" signed message is produced, the verification returns
false.
The precedent mail :
> Hi,
>
> I have a problem with the validation of a signature.
>
> 1) When I pass this document :
> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
> <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
> <ds:CanonicalizationMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
> ... />
> <ds:SignatureMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" ... />
> <ds:Reference URI="#Body" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
> ...
>
> All XML element have the namespace reference xmlns:ds
> ="http://www.w3.org/2000/09/xmldsig#"
>
> And the signature is not valid.
>
>
> 2) Whereas I pass this document :
> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
> <ds:SignedInfo ...> no attibute xmlns:ds="..."
> <ds:CanonicalizationMethod ... /> no attibute xmlns:ds="..."
> <ds:SignatureMethod ... /> no attibute xmlns:ds="..."
> <ds:Reference URI="#Body">
> ...
> The signature is valid.