如何使用keystore.jks对SOAP消息进行签名和加密

时间:2015-07-07 02:52:15

标签: java web-services encryption soap

我是Web服务安全新手,我正在尝试学习如何签署和加密soap消息请求。 我已经阅读了很多与此主题相关的帖子,但似乎有很多不同的方法让我很困惑。

我有一个正常运行的Web服务(SOAP)。我还有一个包含2个条目的keystore.jks文件。

第一个条目类型是trustedCertEntry。 (X.509 / RSA公钥)

第二个条目类型是privateKeyEntry。

我的理解是密钥库包含凭据,信任库包含可信网站(服务器)列表。 所以“... \ jdk1.6.0_19 \ jre \ lib \ security \ cacerts”是我的信任库,keystore.jks是我的密钥库。

我假设我需要使用密钥库凭据来签署和加密soap消息。 但是如何实现它仍然不清楚。

我可以获得X.509证书。

KeyStore ks = KeyStore.getInstance(KEYSTORE_INSTANCE);
ks.load(new FileInputStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray());
ks.getCertificate(KEYSTORE_ALIAS);

我也可以获得私钥:

KeyStore.Entry entry = ks_pk.getEntry(KEYSTORE_ALIAS_PK, new KeyStore.PasswordProtection(pass));

所以我可以从密钥库中获取信息,但我不知道如何处理它以便签署和加密我的SOAP请求消息。

我是否需要将签名添加为另一个SOAPheader元素? 如何加密消息?

任何指针,代码示例和提示都将不胜感激。

1 个答案:

答案 0 :(得分:1)

我正在使用Apache CXF进行客户端和Rampart对SOAP消息进行签名和加密。此Rampart包实现了WSS标准。

在客户端项目中,在pom.xml中添加以下依赖项[检查可用的最新版本]

<dependency>
    <groupId>org.apache.rampart</groupId>
    <artifactId>rampart-policy</artifactId>
    <version>1.4</version>
</dependency>
<dependency>
    <groupId>org.apache.rampart</groupId>
    <artifactId>rampart-core</artifactId>
    <version>1.4</version>
</dependency>

创建一个crypto.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.file=c:/Documents and Settings/garry/keys/client.ks [this is the path to keystore]
org.apache.ws.security.crypto.merlin.keystore.password=client-ks-pass [this is the keystore password]

然后修改Client类以提供Rampart执行签名所需的信息

添加以下导入:

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.ws.security.WSPasswordCallback;

//实现回调处理程序以检索密码

SService ss = new SService(wsdlURL, SERVICE_NAME);
Service port = service.getPort1();
BindingProvider bp = (BindingProvider) port;
Map<String, Object> context = bp.getRequestContext();
//c1 is The alias of the entry in the keystore
context.put(SecurityConstants.SIGNATURE_USERNAME, "c1");
context.put(SecurityConstants.CALLBACK_HANDLER, new 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.getIdentifier();
                if (id.equals("c1")) {
                pwcb.setPassword("c1-pass");
            }
        }
    }
    });
context .put(SecurityConstants.SIGNATURE_PROPERTIES, "crypto.properties");