服务器代码能够在Tomcat服务器中部署应用程序时验证签名。但是在WAS-8.5.5服务器中部署相同的代码时,我得到的响应是"签名无效"。
我使用以下代码在客户端签署soap消息
private static SOAPMessage signSOAPMessage(ByteArrayOutputStream out ){
SOAPMessage soapMessage = null;
MessageFactory messageFactory = null;
ByteArrayOutputStream signOut = new ByteArrayOutputStream();
try{
messageFactory = MessageFactory.newInstance();
soapMessage = messageFactory.createMessage();
org.apache.xml.security.Init.init();
String keystoreType = "JKS";
String keystoreFile = "test.jks";
String keystorePass = "test123";
String privateKeyAlias = "testExample"
String privateKeyPass = "test123";
String certificateAlias = "testExample";
KeyStore ks = KeyStore.getInstance(keystoreType);
FileInputStream fis = new FileInputStream(keystoreFile);
ks.load(fis, keystorePass.toCharArray());
PrivateKey privateKey = (PrivateKey)ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());
javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
db.setErrorHandler(new org.apache.xml.security.utils.IgnoreAllErrorHandler());
String str = new String(out.toByteArray());
InputStream is = new ByteArrayInputStream(str.getBytes());
org.w3c.dom.Document doc = db.parse(is);
Element headerElement = null;
NodeList nodes = doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/","Header");
if(nodes.getLength() == 0){
headerElement = doc.createElementNS("http://schemas.xmlsoap.org/soap/envelope/","Header");
nodes = doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/","Envelope");
if(nodes != null){
Element envelopeElement = (Element)nodes.item(0);
headerElement.setPrefix(envelopeElement.getPrefix());
envelopeElement.appendChild(headerElement);
}
}else{
headerElement = (Element)nodes.item(0);
}
XMLSignature sig = new XMLSignature(doc, "", XMLSignature.ALGO_ID_SIGNATURE_RSA);
headerElement.appendChild(sig.getElement());
Transforms transforms = new Transforms(doc);
transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
sig.addDocument("", transforms, org.apache.xml.security.utils.Constants.ALGO_ID_DIGEST_SHA1);
X509Certificate cert = (X509Certificate) ks.getCertificate(certificateAlias);
sig.addKeyInfo(cert);
sig.addKeyInfo(cert.getPublicKey());
sig.sign(privateKey);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLUtils.outputDOMc14nWithComments(doc, baos);
SOAPPart soapPart = soapMessage.getSOAPPart();
InputStream inputSOAP_REQUEST = new ByteArrayInputStream(new String(baos.toByteArray()).getBytes("UTF-8"));
StreamSource prepMsg = new StreamSource(inputSOAP_REQUEST);
soapPart.setContent(prepMsg);
soapMessage.writeTo(signOut);
baos.close();
}catch(Exception e){
e.printStackTrace();
}
return soapMessage;
}
在服务器端验证我在代码
下面使用的签名 public boolean handleMessage(SOAPMessageContext context) {
boolean validSignature = false;
logger.info("Server executing SOAP Handler");
ByteArrayOutputStream out = new ByteArrayOutputStream();
Boolean outBoundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
logger.info("OutBound Property : "+outBoundProperty);
if (!outBoundProperty) {
try {
SOAPMessage soapMsg = context.getMessage();
soapMsg.writeTo(out);
logger.info("Input Message : "+new String(out.toByteArray()));
InputStream inputSOAP_REQUEST = new ByteArrayInputStream(new String(out.toByteArray()).getBytes("UTF-8"));
org.apache.xml.security.Init.init();
javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
db.setErrorHandler(new org.apache.xml.security.utils.IgnoreAllErrorHandler());
org.w3c.dom.Document doc = db.parse(inputSOAP_REQUEST);
Element sigElement = null;
NodeList nodes = doc.getElementsByTagNameNS(org.apache.xml.security.utils.Constants.SignatureSpecNS,"Signature");
if(nodes.getLength() != 0){
logger.info("Found " + nodes.getLength() + " Signature elements.");
sigElement = (Element)nodes.item(0);
XMLSignature signature = new XMLSignature(sigElement,"");
KeyInfo ki = signature.getKeyInfo();
if(ki != null){
//if(ki.containsX509Data())
//logger.info("Could find a X509Data element in the KeyInfo");
X509Certificate cert = signature.getKeyInfo().getX509Certificate();
if(cert != null){
logger.info("The XML signature is Valid : " + signature.checkSignatureValue(cert));
if(signature.checkSignatureValue(cert)){
validSignature = true;
}else{
generateSoapErrorMessage(soapMsg,"Invalid Signature");
}
}else{
logger.info("Did not find a Certificate");
PublicKey pk = signature.getKeyInfo().getPublicKey();
if(pk != null){
logger.info("The XML signature is Valid : " + signature.checkSignatureValue(pk));
if(signature.checkSignatureValue(pk)){
validSignature = true;
}else{
generateSoapErrorMessage(soapMsg,"Invalid Signature");
}
}else{
logger.error("Did not find a public key, so I can't check the signature");
generateSoapErrorMessage(soapMsg,"Didn't find certificate to verify the signature");
}
}
}else{
generateSoapErrorMessage(soapMsg,"Didn't find any Certificate Information from Signature");
}
}else{
generateSoapErrorMessage(soapMsg,"Signature is missing in header");
}
} catch (SOAPException e) {
logger.error(e.getMessage(),e);
} catch (IOException e) {
logger.error(e.getMessage(),e);
}catch(Exception e){
logger.error(e.getMessage(),e);
}
}
return validSignature;
}