如何手动加密SOAP消息?

12

我使用的是JBoss 4.2.3.GA。在之前的任务中,我使用了JBoss支持的基本加密机制(WS-Security)。例如,我使用密钥库、信任库文件进行消息的加密和签名。通常情况下,在jboss-wsse-*文件中定义了在加密过程中必须使用的密钥别名(以标准方式)。我使用了JBoss in Action书中的ws安全配置。

这很好。加密效果很好。

但在我的当前任务中,我需要手动和动态地指定密钥别名。 任务描述:

  • 我有几个配置文件。在每个配置文件中都可以指定要用于加密消息的公钥别名。

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

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

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

那么问题是:

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

我只是不知道如何开始,要使用什么框架,甚至是否需要使用外部(非JBoss)框架来完成这些操作...


2
我找到了如何使用WSS4J框架指定密钥库位置的方法:http://ws.apache.org/wss4j/config.htmlorg.apache.ws.security.crypto.merlin.keystore.fileorg.apache.ws.security.crypto.merlin.truststore.file - Zaur_M
2
我意识到可以使用jbossws-native框架指定密钥库的绝对路径来加载密钥库。 - Zaur_M
2
例如,如果密钥库位于/tmp目录中,则配置文件如下所示:<?xml version="1.0" encoding="UTF-8"?> <jboss-ws-security ...> <key-store-file>/tmp/server.keystore</key-store-file> ... <trust-store-file>/tmp/server.truststore</trust-store-file> ... </jboss-ws-security> - Zaur_M
最后一个问题:如何在客户端指定加密的别名? - Zaur_M
2
如果你只启用SSL,是否就足够了? - Rob Goodwin
显示剩余3条评论
2个回答

3
如果可能的话,您可以使用Axis2和Rampart。我在类似的情况下成功地使用了它们两个。
Rampart是用于处理安全性的axis2模块,它公开了一个API,允许您定义要使用的密钥库位置和别名,从而允许您动态定义它。 Axis2 Rampart 示例代码:
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);
}

密码回调处理程序:

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

}


0

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>

3:加密替换(包括手动方式)的示例在此处描述,适用于axis2:http://www.javaranch.com/journal/2008/10/web-service-security-encryption-axis2.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接