Java 如何手动加密SOAP消息?

Java 如何手动加密SOAP消息?,java,web-services,security,jboss,ws-security,Java,Web Services,Security,Jboss,Ws Security,我使用JBoss4.2.3.GA。在前面的任务中,我使用了JBoss支持的基本加密机制(WS-Security)。例如,我使用密钥库、信任库文件对消息进行加密和签名。在jboss wsse-*文件中,通常(以标准方式)定义了密钥别名,这些密钥必须在加密过程中使用。我在操作手册中使用了JBoss的ws-security配置 没关系。加密工作正常 但在我当前的任务中,我需要手动和动态地为键指定别名。 任务说明: 我有几个个人资料。在每个配置文件中都可以指定加密消息时必须使用的公钥别名 我的密钥库包

我使用JBoss4.2.3.GA。在前面的任务中,我使用了JBoss支持的基本加密机制(WS-Security)。例如,我使用密钥库、信任库文件对消息进行加密和签名。在jboss wsse-*文件中,通常(以标准方式)定义了密钥别名,这些密钥必须在加密过程中使用。我在操作手册中使用了JBoss的ws-security配置

没关系。加密工作正常

但在我当前的任务中,我需要手动和动态地为键指定别名。 任务说明:

  • 我有几个个人资料。在每个配置文件中都可以指定加密消息时必须使用的公钥别名

  • 我的密钥库包含服务器的私钥/公钥和将向服务器发送消息的客户端的公钥

  • 我需要从配置文件中获取别名,并使用此别名指定的公钥加密消息(在客户端)

  • 所以我需要以某种方式从密钥库加载数据(它必须驻留在文件系统文件夹中,即ear文件之外),从中获取适当的公钥,然后进行加密
  • 之后,我需要将消息发送到远程web服务(服务器端),该服务具有用于解密的私钥
  • 这里我看到了服务器端逻辑的几个变体:web服务使用标准JBoss机制进行解密,或者我可以手动加载密钥库数据并手动进行解密
因此,问题在于:

  • 有没有办法为JBoss指定要从中加载密钥库的文件系统目录
  • 我可以为标准JBoss WSS机制指定加密别名以允许JBoss在加密过程中使用此信息吗
  • 如果我必须进行手动加密/解密,那么如何将多个Java对象包装到WS-message中,然后使用必要的别名对其进行加密,以及如何手动将此消息发送到远程web服务

  • 我只是不知道如何开始,使用什么框架,甚至有必要为此使用外部(非JBoss)框架…

    1&2:定义JBoss的密钥库:

    <jboss-ws-security xmlns="http://www.jboss.com/ws-security/config" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.jboss.com/ws-security/config 
    http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">
      <key-store-file>WEB-INF/wsse.keystore</key-store-file>
      <key-store-password>jbossws</key-store-password>
      <trust-store-file>WEB-INF/wsse.truststore</trust-store-file>
     <trust-store-password>jbossws</trust-store-password>
      <config>
         <sign type="x509v3" alias="wsse"/>
         <requires>
            <signature/>
            </requires>
         </config>
    </jboss-ws-security>
    
    
    WEB-INF/wsse.keystore
    jbossws
    WEB-INF/wsse.truststore
    jbossws
    

    3:此处描述的axis2加密替换(也包括手动)示例:

    如果可能,您可以使用axis2和Rampart。我已经成功地在类似的情况下使用了它们

    Rampart是一个用于处理安全性的axis2模块,它公开了一个API,允许您定义要使用的密钥存储位置和别名,从而允许您动态定义它

    示例代码:

    private static final String CONFIGURATION_CTX = "src/ctx";  
    private static final String KEYSTORE_TYPE = "org.apache.ws.security.crypto.merlin.keystore.type";
    private static final String KEYSTORE_FILE = "org.apache.ws.security.crypto.merlin.file";
    private static final String KEYSTORE_PWD = "org.apache.ws.security.crypto.merlin.keystore.password";
    private static final String PROVIDER = "org.apache.ws.security.components.crypto.Merlin";
    
    private static void engageRampartModules(Stub stub)
    throws AxisFault, FileNotFoundException, XMLStreamException {
        ServiceClient serviceClient = stub._getServiceClient();
    
        engageAddressingModule(stub);   
        serviceClient.engageModule("rampart");
        serviceClient.engageModule("rahas");
    
        RampartConfig rampartConfig = prepareRampartConfig();  
    
        attachPolicy(stub,rampartConfig);
    }
    
    /**
     * Sets all the required security properties.
     * @return rampartConfig - an object containing rampart configurations
     */
    private static RampartConfig prepareRampartConfig() {
        String certAlias = "alias";             //The alias of the public key in the jks file
        String keyStoreFile = "ctx/client.ks";
        String keystorePassword = "pwd";
        String userName = "youusename";
    
    
        RampartConfig rampartConfig = new RampartConfig();
        //Define properties for signing and encription
        Properties merlinProp = new Properties();  
        merlinProp.put(KEYSTORE_TYPE, "JKS");  
        merlinProp.put(KEYSTORE_FILE,keyStoreFile);  
        merlinProp.put(KEYSTORE_PWD, keystorePassword); 
    
        CryptoConfig cryptoConfig = new CryptoConfig();  
        cryptoConfig.setProvider(PROVIDER);  
        cryptoConfig.setProp(merlinProp);  
    
        //Rampart configurations
        rampartConfig.setUser(userName);
        rampartConfig.setUserCertAlias(certAlias);  
        rampartConfig.setEncryptionUser(certAlias);  
        rampartConfig.setPwCbClass("com.callback.tests.PasswordCallbackHandler"); //Password Callbak class
    
        rampartConfig.setSigCryptoConfig(cryptoConfig);  
        rampartConfig.setEncrCryptoConfig(cryptoConfig);
        return rampartConfig;
    }
    
    /**
     * attach the security policy to the stub.
     * @param stub
     * @param rampartConfig
     * @throws XMLStreamException
     * @throws FileNotFoundException
     */
    private static void attachPolicy(Stub stub, RampartConfig rampartConfig) throws XMLStreamException, FileNotFoundException {
        Policy policy = new Policy();
        policy.addAssertion(rampartConfig);
        stub._getServiceClient().getAxisService().getPolicySubject().attachPolicy(policy);
    }
    
    PasswordCallbackHandler:

    import java.io.IOException;
    
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    
    import org.apache.ws.security.WSPasswordCallback;
    
    public class PasswordCallbackHandler implements CallbackHandler {
    
    // @Override
    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pwcb = (WSPasswordCallback) callbacks[i];
            String id = pwcb.getIdentifer();
            switch (pwcb.getUsage()) {
                case WSPasswordCallback.USERNAME_TOKEN: {
                    if (id.equals("pwd")) {
                        pwcb.setPassword("pwd");
                    }
                }
            }
        }
    }
    
    import java.io.IOException;
    导入javax.security.auth.callback.callback;
    导入javax.security.auth.callback.CallbackHandler;
    导入javax.security.auth.callback.UnsupportedCallbackException;
    导入org.apache.ws.security.WSPasswordCallback;
    公共类PasswordCallbackHandler实现CallbackHandler{
    //@覆盖
    公共无效句柄(回调[]回调)引发IOException,
    不支持CallbackException{
    for(int i=0;i

    }

    我发现如何使用WSS4J框架指定密钥存储库位置:org.apache.ws.security.crypto.merlin.keystore.file org.apache.ws.security.crypto.merlin.truststore.fileI意识到可以使用jbossws本机框架加载密钥存储库,指定密钥存储库的绝对路径。例如,如果密钥存储库位于/tmp目录中然后配置文件如下所示:/tmp/server.keystore/tmp/server.truststore。。。要允许安全的web服务与第节中jboss-wsse-server.xml文件中的多个客户机一起工作,必须消除任何用于加密的别名。它被称为动态加密:如果您只启用SSL,这就足够了吗?