简体   繁体   English

签署请求后,Java WSS4J证书从密钥库中消失

[英]Java WSS4J certificate disappears from keystore after signing request

I am using WSS4J to create a soap request signer with a certificate from the keystore. 我正在使用WSS4J使用来自密钥库的证书来创建肥皂请求签名者。 My keystore format is .pkcs and everything works with the first signing, but if I try to run the program to sign more than one document and it doesn't find the certificate in the keystore. 我的密钥库格式是.pkcs,所有内容都可以在第一次签名时使用,但是如果我尝试运行该程序来签署多个文档,并且在密钥库中找不到证书,则可以使用。 It seems to me that the certificate is possibly consumed during signing, which means that it no longer exists for the current environment. 在我看来,证书可能会在签名期间被消耗掉,这意味着当前环境不再存在该证书。 If the program stops and starts again it will sign the first request but the second request fails. 如果程序停止并再次启动,它将签署第一个请求,但第二个请求失败。 I have stepped through multiple times and cannot figure out what the cause is. 我已经执行了多次,无法找出原因。 This code is the last thing being called before the certificate disappears from the keystore this.certUri = getWsConfig().getIdAllocator().createSecureId("X509-", certs[0]); 在证书从密钥库中消失之前,此代码是最后一次调用this.certUri = getWsConfig().getIdAllocator().createSecureId("X509-", certs[0]); this is found on line 556 in WSSecSignature.class . 这可以在WSSecSignature.class 556行找到。 Here is my code. 这是我的代码。

package com.soapsigner;

import java.io.*;
import java.util.Properties;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.ws.security.*;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.Merlin;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecSignature;
import org.apache.ws.security.message.WSSecTimestamp;
import org.w3c.dom.Document;
import org.xml.sax.*;

public class SoapSigner {
    private Crypto crypto;
    private WSSecSignature sig;
    private WSSecTimestamp time;
    private WSSecHeader header; 
    private String alias;
    private String password;
    private String keyFile;
    private String keyFileType;
    private Document signedDoc;
    private String lastError;   
    {
        Logger rootLogger = Logger.getRootLogger();
        rootLogger.setLevel(Level.INFO);
        rootLogger.addAppender(new ConsoleAppender(
                   new PatternLayout("%-6r [%p] %c - %m%n")));
    }   
    //constructor
    public SoapSigner(String XML){
        try {           
            alias = "myalias";
            password = "mypassword";
            keyFile = "/keystore/mykeystore.pkcs";
            keyFileType = "pkcs12";
            sig = new WSSecSignature(); 
            time = new WSSecTimestamp();
            header = new WSSecHeader();
            signedDoc = null;
            lastError = "";         

            Merlin merlin = new Merlin(getCryptoProperties());  
            System.out.println("real signing keystore object: "+merlin.getKeyStore().getCertificate(alias).toString().length()); //Passed
            crypto = merlin;            

            signDocument(xmlToDoc(XML));

            Merlin test = new Merlin(getCryptoProperties());
            System.out.println("test  keystore object: "+test.getKeyStore().getCertificate(alias).toString().length()); //Failed, this is null

        } catch (Exception e) {
            setLastError(e);
        }
    }

    //properties
    public Properties getCryptoProperties(){
        Properties cryptoProperties = new Properties();
        cryptoProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", alias);       
        cryptoProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", password);
        cryptoProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", keyFileType);
        cryptoProperties.setProperty("org.apache.ws.security.crypto.merlin.keystore.file", keyFile);        
        return cryptoProperties;        
    }

    //sign the document
    public void signDocument(Document doc){             
        try {   
            header.setMustUnderstand(true);
            sig.setSignatureAlgorithm(WSConstants.C14N_EXCL_OMIT_COMMENTS);
            sig.setSignatureAlgorithm(WSConstants.RSA);
            sig.setUserInfo(alias, password);
            sig.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE); 
            header.insertSecurityHeader(doc);
            sig.build(doc, crypto, header);
            time.build(doc, header);
            signedDoc = doc;
        } catch (Exception e) {         
            setLastError(e);
        }           
    }

    //get the signed document
    public Document getDocument(){      
        return signedDoc;       
    }

    //get the signed xml
    public String getXML(){
        return getStringFromDoc(getDocument()).trim();
    }

    //get last error
    public String getLastError(){
        return lastError;
    }

    //set last error
    private void setLastError(Throwable e){
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        lastError += "     NEXT ERROR     "+sw.toString();
        e.printStackTrace();
    }   

    //document to string
    public String getStringFromDoc(Document doc){
        try
        {
           DOMSource domSource = new DOMSource(doc);
           StringWriter writer = new StringWriter();
           StreamResult result = new StreamResult(writer);
           TransformerFactory tf = TransformerFactory.newInstance();
           Transformer transformer = tf.newTransformer();
           transformer.transform(domSource, result);
           writer.flush();
           return writer.toString();
        }
        catch(Exception e)
        {
           setLastError(e);
           return null;
        }
    }

    //string to document
    public Document xmlToDoc(String XML){   
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db;     
            db = dbf.newDocumentBuilder();      
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(XML));
            Document doc = db.parse(is);
        return doc;
        } catch (Exception e) {
            setLastError(e);
            return null;
        }       
    }

    //main
    public static void main(String[] args){     
        String XML1 = "<?xml version='1.0' encoding='UTF-8'?><soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> <soap:Body> <test1></test1> </soap:Body> </soap:Envelope>";  
        String XML2 = "<?xml version='1.0' encoding='UTF-8'?><soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> <soap:Body> <test2></test2> </soap:Body> </soap:Envelope>";  
        new SoapSigner(XML1);           
        new SoapSigner(XML2);               
    }
}

Also, I would like to turn the doDebug mode on in the WSSecBase.class but it won't showup in the variable viewer to toggle the value. 另外,我想打开doDebug模式上的WSSecBase.class但它不会在变量观众showup切换值。 I created a breakpoint in the constructor and set it to be watched but it never shows up to toggle. 我在构造函数中创建了一个断点,并将其设置为受监视,但它从未显示过切换。

Your testcase works fine for me with a .p12 from WSS4J test source on the latest WSS4J SNAPSHOT code. 在最新的WSS4J SNAPSHOT代码上,使用来自WSS4J测试源的.p12,您的测试用例对我来说很好用。 Are you using an older version of WSS4J? 您正在使用旧版本的WSS4J吗? If so please try with the latest releases + see if it works. 如果是这样,请尝试使用最新版本+看看是否可行。 If not, then please create a test-case with your .p12 file + create a new issue in the WSS4J JIRA: 如果不是,那么请使用.p12文件创建一个测试用例,并在WSS4J JIRA中创建一个新的问题:

https://issues.apache.org/jira/browse/WSS https://issues.apache.org/jira/browse/WSS

Colm. 科尔姆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM