加密 Crypto 属性 文件中的密码

Encrypting passwords in Crypto property files

问题

我正在使用 Apache CXF 3.0.7,并且读到,在 new features 中,您可以在 Crypto 属性文件中存储密钥库密码的(BASE-64 编码)加密版本,但是不知道怎么加,没找到这个实现的例子。

在 apache 网站上说:

A typical example of the contents of a Crypto properties file (for Signature creation) is as follows:

 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=security
 org.apache.wss4j.crypto.merlin.keystore.alias=wss40
 org.apache.wss4j.crypto.merlin.keystore.file=keys/wss40.jks 

Note that the password used to load the keystore is in cleartext. One of the new features of Apache WSS4J 2.0.0 is the ability to instead store a (BASE-64 encoded) encrypted version of the keystore password in the Crypto properties file. A new PasswordEncryptor interface is defined to allow for the encryption/decryption of passwords. A default implementation is now provided based on Jasypt called JasyptPasswordEncryptor, which uses "PBEWithMD5AndTripleDES".

The WSPasswordCallback class has an additional "usage" called WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD, which is used to return the master password for use with the PasswordEncryptor implementation. When WSS4J is loading a Crypto implementation via a properties file, and it encounters a password encrypted in the format "ENC(encoded encrypted password)", it queries a CallbackHandler for a password via this WSPasswordCallback usage tag. It is possible to pass a custom PasswordEncryptor implementation to WSS4J via the new configuration tag ConfigurationConstants.PASSWORD_ENCRYPTOR_INSTANCE ("passwordEncryptorInstance").

It is possible to pass a custom PasswordEncryptor implementation to WSS4J via the new configuration tag ConfigurationConstants.PASSWORD_ENCRYPTOR_INSTANCE ("passwordEncryptorInstance").

我想我必须在我的属性文件中声明类似这样的内容:

org.apache.wss4j.crypto.merlin.keystore.password=ENC(?????)

但我不知道如何使用默认的 JasyptPasswordEncryptor 来加密我的密码。 另外,我想在我的 CallbackHandler 中我会有类似的东西:

if (usage==WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD){
                ????
    }

解决方案

好的,通过测试 运行,我测试了我的解决方案,现在可以正常工作了。

  1. 下载jasypt-1.9.2-dist.zip
  2. 使用此命令获取加密密码 加密输入=real_keystore_password 密码=master_password 算法=PBEWithMD5AndTripeDES
  3. 复制输出(示例: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 实现 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");
            }
        }           
    }
    

    }

就是这样......现在我必须弄清楚如何在外部 local.property、Spring 等中让它工作......但这是另一段历史.. 谢谢!

这个测试应该可以帮助你:https://svn.apache.org/repos/asf/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/message/PasswordEncryptorTest.java

您可以像在测试中一样,通过使用主密码实例化JasyptPasswordEncryptor 来获取加密密码,并对密钥库密码进行加密。然后将其复制到您的加密属性中:

https://svn.apache.org/repos/asf/webservices/wss4j/trunk/ws-security-dom/src/test/resources/crypto_enc.properties