簡體   English   中英

如何讓WSS4J從回調中加載密鑰庫密碼?

[英]How to make WSS4J load the keystore password from a callback?

我正在使用Apache CXF來構建Web服務。 它使用Apache WSS4J來提供WS-Security功能。 我需要發出SOAP請求,必須簽名。

這是我傳遞給WSS4J的屬性文件的內容:

org.apache.ws.security.crypto.provider = org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type = PKCS12
org.apache.ws.security.crypto.merlin.keystore.provider = BC
org.apache.ws.security.crypto.merlin.keystore.password = 12345678
org.apache.ws.security.crypto.merlin.keystore.alias = my-alias
org.apache.ws.security.crypto.merlin.keystore.file = my_certificate.p12

我希望擺脫那條線,我的密碼寫成純文本。 我刪除了那一行並為我的WSS4JOutInterceptor提供了一個密碼回調處理程序,就像上面的代碼一樣:

public SoapInterceptor newSignerInterceptor() {
    Map<String, Object> outProps = new HashMap<String, Object>();
    outProps.put(WSHandlerConstants.ACTION, "Signature");
    outProps.put(WSHandlerConstants.USER, config.getKeyAlias());
    outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
    outProps.put(WSHandlerConstants.USE_REQ_SIG_CERT, WSHandlerConstants.SIGNATURE_USER);
    outProps.put(WSHandlerConstants.USE_SINGLE_CERTIFICATE, "false");
    outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, this.getClass().getName());
    outProps.put(WSHandlerConstants.SIG_PROP_FILE, config.getPropertiesFileName());
    return new WSS4JOutInterceptor(outProps);

}

@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    for (int i = 0; i < callbacks.length; i++) {
        if (callbacks[i] instanceof WSPasswordCallback) {
            ((WSPasswordCallback) callbacks[i]).setPassword(password);
        }
    }
}

但那沒用。 它在屬性文件中找不到密碼,並使用默認密碼“security”。

如何讓它使用回調來獲取密碼?

您可以實現CallbackHandler

public class PasswordCallbackHandler implements CallbackHandler {

    @Override
    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for(Callback callBack:callbacks){
            if(callBack instanceof WSPasswordCallback){
                ((WSPasswordCallback)callBack).setPassword("password");
            }
        }
    }
}

然后將處理程序添加到屬性:

outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, PasswordCallbackHandler.class);

您還可以使用PW_CALLBACK_REF來設置處理程序的引用。

Merlin不會調用Keystore密碼的回調,因此密碼必須始終位於屬性文件中。 幸運的是它可以加密。

這里很好地描述了解決方案: 加密Crypto屬性文件中的密碼

從以上鏈接復制的解決方案:

  1. 下載jasypt-1.9.2-dist.zip
  2. 使用此命令獲取編碼密碼encrypt input=real_keystore_password password=master_password algorithm=PBEWithMD5AndTripleDES
  3. 復制OUTPUT(例如:0laAaRahTQJzlsDu771tYi)
  4. 當您使用此算法時,您需要Java密碼術擴展(JCE)無限強度。 放入你的JDK。
  5. 將編碼輸出放在屬性中

     org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin org.apache.wss4j.crypto.merlin.keystore.type=jks org.apache.wss4j.crypto.merlin.keystore.password=ENC(0laAaRahTQJzlsDu771tYi) org.apache.wss4j.crypto.merlin.keystore.alias=my_alias org.apache.wss4j.crypto.merlin.keystore.file=/etc/cert/my_keystore.jks 
  6. 在CallbackHandler中,放置用於生成編碼的master_password:

     public class WsPasswordHandler implements CallbackHandler { @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback: callbacks){ WSPasswordCallback pwdCallback= (WSPasswordCallback) callback; final int usage =pwdCallback.getUsage(); if (usage == WSPasswordCallback.SIGNATURE || usage==WSPasswordCallback.DECRYPT) { pwdCallback.setPassword("parKeyPassword"); } if (usage==WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD){ pwdCallback.setPassword("master_password"); } } } 

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM