簡體   English   中英

簽署請求后,Java WSS4J證書從密鑰庫中消失

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

我正在使用WSS4J使用來自密鑰庫的證書來創建肥皂請求簽名者。 我的密鑰庫格式是.pkcs,所有內容都可以在第一次簽名時使用,但是如果我嘗試運行該程序來簽署多個文檔,並且在密鑰庫中找不到證書,則可以使用。 在我看來,證書可能會在簽名期間被消耗掉,這意味着當前環境不再存在該證書。 如果程序停止並再次啟動,它將簽署第一個請求,但第二個請求失敗。 我已經執行了多次,無法找出原因。 在證書從密鑰庫中消失之前,此代碼是最后一次調用this.certUri = getWsConfig().getIdAllocator().createSecureId("X509-", certs[0]); 這可以在WSSecSignature.class 556行找到。 這是我的代碼。

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);               
    }
}

另外,我想打開doDebug模式上的WSSecBase.class但它不會在變量觀眾showup切換值。 我在構造函數中創建了一個斷點,並將其設置為受監視,但它從未顯示過切換。

在最新的WSS4J SNAPSHOT代碼上,使用來自WSS4J測試源的.p12,您的測試用例對我來說很好用。 您正在使用舊版本的WSS4J嗎? 如果是這樣,請嘗試使用最新版本+看看是否可行。 如果不是,那么請使用.p12文件創建一個測試用例,並在WSS4J JIRA中創建一個新的問題:

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

科爾姆。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM