通过org.apache.ws.security.components.crypto.Merlin来实现对客户端发出的报文进行WSS加密,在1.6以后的版本中,client_sign.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=keyStorePassword
org.apache.ws.security.crypto.merlin.keystore.alias=myAlias
org.apache.ws.security.crypto.merlin.keystore.file=client_keystore.jks
org.apache.ws.security.crypto.merlin.file=client_keystore.jks
另外WS官方建议,将1.5.x升级为1.6.x,因为在1.6.x中修复了一些安全性问题,
The 1.5.x series of releases of WSS4J is deprecated. You should switch to a 1.6.x release as a matter of priority, as this branch contains up to date security fixes. For example, WSS4J 1.6.x uses the "secure validation" mode of Apache XML Security for Java, which protects against a number of attacks on XML Signature.
如果想知道Merlin中的所有配置项的键,可以查看这里:http://ws.apache.org/wss4j/apidocs/index.html?constant-values.html,在其中搜索“org.apache.ws.security.components.crypto.Merlin“就可以看到了。
如果不知道如何使用merlin,可以查看merlin的使用示例:http://ws.apache.org/wss4j/xref/org/apache/ws/security/components/crypto/Merlin.html。
如果你的client keystore是没有密码的,那么可以实现自己的merlin,用以解决空密码的问题,以下两个自己实现的Merlin分别适用于wss1.5.x及1.6.x:
适用于1.5.x的空密码的BlankPasswordMerlin:
public class BlankPasswordMerlin implements Crypto {
private Merlin merlin;
private static final String CRYPTO_KEYSTORE_PASSWORD = "org.apache.ws.security.crypto.merlin.keystore.password";
public BlankPasswordMerlin(Properties properties) throws CredentialException,
IOException {
setKeyStorePassword(properties);
merlin = new Merlin(properties);
}
public BlankPasswordMerlin(Properties properties, ClassLoader loader)
throws CredentialException, IOException {
setKeyStorePassword(properties);
merlin = new Merlin(properties, loader);
}
private void setKeyStorePassword(Properties properties) {
properties.put(CRYPTO_KEYSTORE_PASSWORD, "");
}
public X509Certificate loadCertificate(InputStream in)
throws WSSecurityException {
return merlin.loadCertificate(in);
}
public X509Certificate[] getX509Certificates(byte[] data, boolean reverse)
throws WSSecurityException {
return merlin.getX509Certificates(data, reverse);
}
public byte[] getCertificateData(boolean reverse, X509Certificate[] certs)
throws WSSecurityException {
return merlin.getCertificateData(reverse, certs);
}
public PrivateKey getPrivateKey(String alias, String password)
throws Exception {
return merlin.getPrivateKey(alias, password);
}
public X509Certificate[] getCertificates(String alias)
throws WSSecurityException {
return merlin.getCertificates(alias);
}
public String getAliasForX509Cert(Certificate cert)
throws WSSecurityException {
return merlin.getAliasForX509Cert(cert);
}
public String getAliasForX509Cert(String issuer) throws WSSecurityException {
return merlin.getAliasForX509Cert(issuer);
}
public String getAliasForX509Cert(String issuer, BigInteger serialNumber)
throws WSSecurityException {
return merlin.getAliasForX509Cert(issuer, serialNumber);
}
public String getAliasForX509Cert(byte[] skiBytes)
throws WSSecurityException {
return merlin.getAliasForX509Cert(skiBytes);
}
public String getDefaultX509Alias() {
return merlin.getDefaultX509Alias();
}
public byte[] getSKIBytesFromCert(X509Certificate cert)
throws WSSecurityException {
return merlin.getSKIBytesFromCert(cert);
}
public String getAliasForX509CertThumb(byte[] thumb)
throws WSSecurityException {
return merlin.getAliasForX509CertThumb(thumb);
}
public KeyStore getKeyStore() {
return merlin.getKeyStore();
}
public CertificateFactory getCertificateFactory()
throws WSSecurityException {
return merlin.getCertificateFactory();
}
public boolean validateCertPath(X509Certificate[] certs)
throws WSSecurityException {
return merlin.validateCertPath(certs);
}
public String[] getAliasesForDN(String subjectDN)
throws WSSecurityException {
return merlin.getAliasesForDN(subjectDN);
}
}
适用于1.6.x的空密码的BlankPasswordMerlin:
public class BlankPasswordMerlin implements Crypto {
private Merlin merlin;
private static final String CRYPTO_KEYSTORE_PASSWORD = "org.apache.ws.security.crypto.merlin.keystore.password";
public BlankPasswordMerlin(Properties properties) throws CredentialException, IOException {
setKeyStorePassword(properties);
this.merlin = new Merlin(properties);
}
public BlankPasswordMerlin(Properties properties, ClassLoader loader) throws CredentialException, IOException {
setKeyStorePassword(properties);
this.merlin = new Merlin(properties, loader);
}
private void setKeyStorePassword(Properties properties) {
properties.put("org.apache.ws.security.crypto.merlin.keystore.password", "");
}
public X509Certificate loadCertificate(InputStream in) throws WSSecurityException {
return this.merlin.loadCertificate(in);
}
public byte[] getSKIBytesFromCert(X509Certificate cert) throws WSSecurityException {
return this.merlin.getSKIBytesFromCert(cert);
}
public KeyStore getKeyStore() {
return this.merlin.getKeyStore();
}
public CertificateFactory getCertificateFactory() throws WSSecurityException {
return this.merlin.getCertificateFactory();
}
public byte[] getBytesFromCertificates(X509Certificate[] certs) throws WSSecurityException {
return this.merlin.getBytesFromCertificates(certs);
}
public X509Certificate[] getCertificatesFromBytes(byte[] certs) throws WSSecurityException {
return this.merlin.getCertificatesFromBytes(certs);
}
public String getCryptoProvider() {
return this.merlin.getCryptoProvider();
}
public String getDefaultX509Identifier() throws WSSecurityException {
return this.merlin.getDefaultX509Identifier();
}
public PrivateKey getPrivateKey(X509Certificate cert, CallbackHandler handler) throws WSSecurityException {
return this.merlin.getPrivateKey(cert, handler);
}
public PrivateKey getPrivateKey(String param1, String param2) throws WSSecurityException {
return this.merlin.getPrivateKey(param1, param2);
}
public X509Certificate[] getX509Certificates(CryptoType cryptoType) throws WSSecurityException {
return this.merlin.getX509Certificates(cryptoType);
}
public String getX509Identifier(X509Certificate cert) throws WSSecurityException {
return this.merlin.getX509Identifier(cert);
}
public void setCertificateFactory(String provider, CertificateFactory certFactory) {
this.merlin.setCertificateFactory(provider, certFactory);
}
public void setCryptoProvider(String provider) {
this.merlin.setCryptoProvider(provider);
}
public void setDefaultX509Identifier(String identifier) {
this.merlin.setDefaultX509Identifier(identifier);
}
public boolean verifyTrust(X509Certificate[] certs) throws WSSecurityException {
return this.merlin.verifyTrust(certs);
}
public boolean verifyTrust(PublicKey publicKey) throws WSSecurityException {
return this.merlin.verifyTrust(publicKey);
}
public boolean verifyTrust(X509Certificate[] certs, boolean boo) throws WSSecurityException {
return this.merlin.verifyTrust(certs, boo);
}
}
org.apache.ws.security.crypto.provider=com.xxx.BlankPasswordMerlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.alias=sre
org.apache.ws.security.crypto.merlin.file=sre.jks