我是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元素? 如何加密消息?
任何指针,代码示例和提示都将不胜感激。
答案 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");