2

我正在研究 Web 服务安全性,尝试在服务器和客户端之间加密和签署 SOAP 消息。我使用了 BouncyCastle、WSS4j 和 SOAP 处理程序。

为了测试我的工作,我在服务器端和客户端都使用了相同的密钥库文件。我按照网上的一些教程进行操作,它起作用了:一侧发送的消息经过加密和签名,然后在另一侧成功解密.

但是现在我为服务器和客户端生成了不同的证书,并将客户端的证书导入到服务器的 jks 文件中,反之亦然,我似乎无法弄清楚如何完成任务。它仍在加密和签名,就好像它只有一个没有导入证书的 jks 文件一样。下面是代码:

Crypt_handler.java
public class Crypt_handler implements SOAPHandler<SOAPMessageContext> , CallbackHandler{

public Properties prop;

public InputStream input= null;



public Crypt_handler ()  {


    try {
        prop=new Properties();
        input = new FileInputStream("config.properties");
        if(input==null){
            System.out.println("Sorry, unable to find " );
        return;}
        prop.load(input);

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

public boolean handleMessage(SOAPMessageContext messageContext) {

   try {
       // got the message from the context
       SOAPMessage msg = messageContext.getMessage();

      // is outgoing?
     Boolean isOutGoing = (Boolean) messageContext
               .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

       if (isOutGoing) {

           // if it is outgoing code and sign


           crypt.EncryptUtil.EncryptSOAPEnvelope(msg, prop);
           crypt.EncryptUtil.SignSOAPEnvelope(msg, prop);


       } else {

           // if it is incooming decode and check signature.
           crypt.EncryptUtil.CheckSignatureAndDecode(msg, this , prop);

       }

   } catch (Exception ex) {
       ex.printStackTrace();

       throw new RuntimeException(ex.getMessage());
   }

   return true;




}

  public boolean handleFault(SOAPMessageContext context) {

    System.out.println("Server : handleFault()......");

    return true;
   }

 public void close(MessageContext context) {
    System.out.println("Server : close()......");
  }


 public Set<QName> getHeaders() {

Set<QName> HEADERS = new HashSet<QName>();

HEADERS.add(new QName(WSConstants.WSSE_NS, "Security"));
HEADERS.add(new QName(WSConstants.WSSE11_NS, "Security"));
HEADERS.add(new QName(WSConstants.ENC_NS, "EncryptedData"));

return HEADERS;

}

 private void generateSOAPErrMessage(SOAPMessage msg, String reason) {
   try {
      SOAPBody soapBody = msg.getSOAPPart().getEnvelope().getBody();
      SOAPFault soapFault = soapBody.addFault();
      soapFault.setFaultString(reason);
      throw new SOAPFaultException(soapFault); 
   }
   catch(SOAPException e) { }
  }

 @SuppressWarnings("deprecation")
 public void handle(Callback[] callbacks) throws IOException,

        UnsupportedCallbackException {

     String password;

     for (Callback cb : callbacks) {

         if (cb instanceof WSPasswordCallback) {

              WSPasswordCallback pc = (WSPasswordCallback) cb;

             try {

                 password = /*prop.getProperty("password")*/"password";

             } catch (Exception e) {


                 throw new UnsupportedCallbackException(pc,  "failure recovering the key in the properties");

             }

            if (pc.getIdentifer() != null) {

                 pc.setPassword(password);

             }

        }

       }

    }

 }

EncryptUtil.java:

public class EncryptUtil{

@SuppressWarnings( { "unchecked", "deprecation" })
public
static void CheckSignatureAndDecode(SOAPMessage msg,   CallbackHandler cb,Properties prop) throws WSSecurityException,            TransformerConfigurationException, TransformerException,  SOAPException, IOException, Exception {

    WSSecurityEngine secEngine = new WSSecurityEngine();

    WSSignEnvelope signer = new WSSignEnvelope();

    String alias = prop.getProperty("alias");// login of jks file
    String password = prop.getProperty("password");// password of jks file


    signer.setUserInfo("client", password);


    Crypto crypto = CryptoFactory.getInstance(prop);
    Document doc = toDocument(msg);

  //after we set the encrypt stuff the processsecurity does all the work

    Vector v = secEngine.processSecurityHeader(doc, null, cb, crypto);

    if (v == null) {

        throw new Exception("Access not granted.");

    }

    //put the decoded message into the object
    updateSOAPMessage(doc, msg);
  }



  /**
  * Updates the message with the unencrypt form
  */


   private static SOAPMessage updateSOAPMessage(Document doc, SOAPMessage message) throws SOAPException {

    DOMSource domSource = new DOMSource(doc);
    message.getSOAPPart().setContent(domSource);

    return message;

   } 



   /**
   * Changes the SOAPMessage to a dom.Document.
   */


   public static org.w3c.dom.Document toDocument(SOAPMessage soapMsg)             throws SOAPException, TransformerException {

    Source src = soapMsg.getSOAPPart().getContent();

    TransformerFactory tf = TransformerFactory.newInstance();

    Transformer transformer = tf.newTransformer();

    DOMResult result = new DOMResult();
    transformer.transform(src, result);
    return (Document) result.getNode();

   }

  /**
   * Signs  a SOAPMessage
   * 
   * @param mensaje
   * @throws Exception
  */
   @SuppressWarnings("deprecation")
   public
   static void SignSOAPEnvelope(SOAPMessage mensaje, Properties prop) throws Exception {

    // WSSignEnvelope signs a SOAP envelope according to the
    // WS Specification (X509 profile) and adds the signature data
    // to the envelope.
    WSSignEnvelope signer = new WSSignEnvelope();

    String alias = prop.getProperty("alias");// "autentiaserver";
    String password = prop.getProperty("password");// "changeit";

    signer.setUserInfo(alias, password);

    Crypto crypto = CryptoFactory.getInstance(prop);

    Document doc =  toDocument(mensaje);
    signer.setMustUnderstand(false);

    Document signedDoc =  signer.build( doc, crypto);
    DOMSource domSource = new DOMSource( signedDoc);
    mensaje.getSOAPPart().setContent(domSource);

   }


   /**
    * Codes a SOAPMessage.
   */

  @SuppressWarnings("deprecation")
  public
  static void EncryptSOAPEnvelope(SOAPMessage mensaje,Properties prop) throws Exception   {


    // WSSignEnvelope signs a SOAP envelope according to the
    // WS Specification (X509 profile) and adds the signature data
    // to the envelope.
    WSEncryptBody encriptador = new WSEncryptBody();


    String alias = prop.getProperty("alias");
    String password = prop.getProperty("password");


    encriptador.setUserInfo(alias, password);

   Crypto crypto = CryptoFactory.getInstance(prop);



    Document doc =  toDocument(mensaje);

    encriptador.setMustUnderstand(false);

    Document signedDoc =  encriptador.build( doc, crypto);

    DOMSource domSource = new DOMSource( signedDoc);
    mensaje.getSOAPPart().setContent(domSource);
}
}

这是我的 config.properties 文件:

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=password
org.apache.ws.security.crypto.merlin.keystore.alias=first
org.apache.ws.security.crypto.merlin.file=/home/user/workspace/crypt_server/keystore.jks
alias=first
password=password

任何帮助,将不胜感激。提前致谢。

4

0 回答 0