Java中SOAP消息中的数字签名XML问题

Java中SOAP消息中的数字签名XML问题,java,xml,soap,Java,Xml,Soap,我有以下问题: 我正在制作一个应用程序,它将一个已经数字签名的XML证书发送给一个官方的政府Web服务 当我生成SOAP消息时,我将整个文件复制到一个字符串中(我使用了几种技术:Guava的file.toString、Files.readAllBytes(path.get(path)),并使用所有相关的编码(UTF-8和ISO-8859-1,因为文档是西班牙语的).在发送soap消息之前,我使用logger存储soap消息的内容 问题是webservice给了我一个“无效签名”的答案,但是当我从

我有以下问题:

我正在制作一个应用程序,它将一个已经数字签名的XML证书发送给一个官方的政府Web服务

当我生成SOAP消息时,我将整个文件复制到一个字符串中(我使用了几种技术:Guava的file.toString、Files.readAllBytes(path.get(path)),并使用所有相关的编码(UTF-8和ISO-8859-1,因为文档是西班牙语的).在发送soap消息之前,我使用logger存储soap消息的内容

问题是webservice给了我一个“无效签名”的答案,但是当我从日志中复制soap消息并通过SoapUI发送时,webservice接受签名的证书

下面是实现神奇效果的代码:

public class SOAPClientSAAJ {

public static void SendMessage(String file, String rscpath) throws Exception {
    // Create SOAP Connection
    SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
    SOAPConnection soapConnection = soapConnectionFactory.createConnection();
    GetCurrentTimeStamp cts = new GetCurrentTimeStamp();
    Logger logger = Logger.getLogger("MyLog");  
    FileHandler fh;  

    String logfile = rscpath+cts.GetCurrentTimeStamp()+".log";
    try {  

        // This block configure the logger with handler and formatter  
        fh = new FileHandler(logfile);  
        logger.addHandler(fh);
        SimpleFormatter formatter = new SimpleFormatter();  
        fh.setFormatter(formatter);  

    } catch (SecurityException e) {  
        e.printStackTrace();  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  

    // Send SOAP Message to SOAP Server
    String url = "http://172.25.1.220:8080/SGPRTWebServices/RecepcionCrt";
    SOAPMessage soapResponse = null;
    SOAPMessage soapmsg = null;
    logger.info(file.substring(file.lastIndexOf(File.separator)));
    soapmsg = createSOAPRequest(file);
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    soapmsg.writeTo(out);
    String msg = new String(out.toByteArray());
    logger.info(msg);
    out = null;
    msg = null;

    try{
    soapResponse = soapConnection.call(soapmsg, url);

    SOAPPart sp = soapResponse.getSOAPPart();
    SOAPEnvelope se = sp.getEnvelope();
    SOAPBody sb = se.getBody();
    ByteArrayOutputStream out2 = new ByteArrayOutputStream();
    soapResponse.writeTo(out2);
    msg = new String(out2.toByteArray());
    logger.info(msg);

    }catch (Exception ex) {
        logger.info(ex.toString());
    }
    soapConnection.close();
}

private static SOAPMessage createSOAPRequest(String confFilePath) throws Exception {
    MessageFactory messageFactory = MessageFactory.newInstance();
    SOAPMessage soapMessage = messageFactory.createMessage();
    SOAPPart soapPart = soapMessage.getSOAPPart();

    String serverURI = "http://recepcionCrt.ws.sgprt.mtt.cl/";

    Path pat =Paths.get(confFilePath);
    Charset charset = StandardCharsets.ISO_8859_1;

    String texto = "<![CDATA[";
    File fl = pat.toFile();
    String content =  Files.toString(fl, charset);
    texto = texto + content +"]]>";

    SOAPEnvelope envelope = soapPart.getEnvelope();
    envelope.setEncodingStyle("UTF-8");
    SOAPBody soapBody = envelope.getBody();
    soapBody.addNamespaceDeclaration("ns2", serverURI);
    SOAPElement soapBodyElem = soapBody.addChildElement ("recepcionCRT","ns2");
    SOAPElement soapBodyElem1 = soapBodyElem.addChildElement ("arg0");

    soapBodyElem1.addTextNode(texto);
    MimeHeaders headers = soapMessage.getMimeHeaders();
    headers.addHeader("SOAPAction", serverURI  + "recepcionCRT");
    soapMessage.saveChanges();

    return soapMessage;
}
}
公共类SOAPClientSAAJ{
公共静态void SendMessage(字符串文件,字符串rscpath)引发异常{
//创建SOAP连接
SOAPConnectionFactory SOAPConnectionFactory=SOAPConnectionFactory.newInstance();
SOAPConnection-SOAPConnection=soapConnectionFactory.createConnection();
GetCurrentTimeStamp cts=新的GetCurrentTimeStamp();
Logger=Logger.getLogger(“MyLog”);
文件处理程序fh;
字符串logfile=rscpath+cts.GetCurrentTimeStamp()+“.log”;
试试{
//此块使用处理程序和格式化程序配置记录器
fh=新文件处理程序(日志文件);
记录器.addHandler(fh);
SimpleFormatter formatter=新的SimpleFormatter();
设置格式化程序(格式化程序);
}catch(SecurityException e){
e、 printStackTrace();
}捕获(IOE){
e、 printStackTrace();
}  
//向SOAP服务器发送SOAP消息
字符串url=”http://172.25.1.220:8080/SGPRTWebServices/RecepcionCrt";
SOAPMessage soapResponse=null;
SOAPMessage soapmsg=null;
logger.info(file.substring(file.lastIndexOf(file.separator));
soapmsg=createSOAPRequest(文件);
ByteArrayOutputStream out=新建ByteArrayOutputStream();
soapmsg.writeTo(out);
String msg=新字符串(out.toByteArray());
logger.info(msg);
out=null;
msg=null;
试一试{
soapResponse=soapConnection.call(soapmsg,url);
SOAPPart sp=soapResponse.getSOAPPart();
SOAPEnvelope se=sp.getEnvelope();
SOAPBody sb=se.getBody();
ByteArrayOutputStream out2=新建ByteArrayOutputStream();
soapResponse.writeTo(out2);
msg=新字符串(out2.toByteArray());
logger.info(msg);
}捕获(例外情况除外){
logger.info(例如toString());
}
soapConnection.close();
}
私有静态SOAPMessage createSOAPRequest(字符串confFilePath)引发异常{
MessageFactory MessageFactory=MessageFactory.newInstance();
SOAPMessage SOAPMessage=messageFactory.createMessage();
SOAPPart SOAPPart=soapMessage.getSOAPPart();
字符串serverURI=”http://recepcionCrt.ws.sgprt.mtt.cl/";
Path pat=Path.get(confFilePath);
字符集字符集=标准字符集.ISO_8859_1;
字符串texto=“”;
SOAPEnvelope=soapPart.getEnvelope();
信封。设置编码样式(“UTF-8”);
SOAPBody SOAPBody=envelope.getBody();
addNamespaceDeclaration(“ns2”,serverURI);
SOAPElement soapBodyElem=soapBody.addChildElement(“recepcionCRT”、“ns2”);
SOAPElement soapBodyElem1=soapBodyElem.addChildElement(“arg0”);
soapBodyElem1.addTextNode(texto);
MimeHeaders=soapMessage.getMimeHeaders();
headers.addHeader(“SOAPAction”,serverURI+“recepcionCRT”);
soapMessage.saveChanges();
返回消息;
}
}

这里:就像wsdl一样,一个有效的证书和一个有效的soap消息。

事实证明,问题出在通信过程中。我必须使用jdk中的importws工具加载接口和类别,以便与提供者通信。一旦我这样做,消息就被正确接收,签名也得到验证