8

我有一个这样定义的spring TextEncryptor

<bean id="textEncryptor" class="org.springframework.security.crypto.encrypt.Encryptors"
                                                  factory-method="text">
        <constructor-arg value="${security.encryptPassword}" />
        <constructor-arg value="${security.encryptSalt}" />
</bean>

哪个是这些属性

security.encryptPassword=47582920264f212c566d5e5a6d
security.encryptSalt=39783e315e6a207e733d6f4141

这在我的本地环境中运行良好。当我部署到 Heroku 我得到

java.lang.IllegalArgumentException: Unable to initialize due to invalid secret key
at org.springframework.security.crypto.encrypt.CipherUtils.initCipher(CipherUtils.java:110)
at org.springframework.security.crypto.encrypt.AesBytesEncryptor.encrypt(AesBytesEncryptor.java:65)
at org.springframework.security.crypto.encrypt.HexEncodingTextEncryptor.encrypt(HexEncodingTextEncryptor.java:36)
...
Caused by: java.security.InvalidKeyException: Illegal key size
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:972)
at javax.crypto.Cipher.implInit(Cipher.java:738)
at javax.crypto.Cipher.chooseProvider(Cipher.java:797)
at javax.crypto.Cipher.init(Cipher.java:1276)
at javax.crypto.Cipher.init(Cipher.java:1215)
at org.springframework.security.crypto.encrypt.CipherUtils.initCipher(CipherUtils.java:105)
... 53 more

所以我尝试了一些较小的键,但我总是遇到同样的问题。在 Heroku 上使用的正确密钥大小是多少?

4

3 回答 3

13

我的回答有点晚了,但我写它是为了帮助有需要的人。默认情况下,spring security 使用 256 位密钥进行加密。默认情况下,JDK 不允许这样做,它仅支持最多 128 位密钥。

要解决此问题,您需要从 oracle下载local_policy.jarUS_export_policy.jar jar( Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 下载)并将它们替换到 jdk_path/jre/lib/security/ 中。确保重新启动应用程序服务器以使更改生效。

另外,我不会将密钥放在属性文件中。相反,我建议您将其放在密钥库中。如果您需要帮助,请告诉我。

于 2013-07-14T07:11:36.037 回答
7

所以我想我已经得出结论 Heroku 不支持 256 位 AEP,这是 spring-security 中的库存 TextEncoders 使用的。

相反,我使用Java Simplified Encryption库中的 BasicTextEncryptor 作为替代后端,并实现了 TextEncryptor 接口。

它不太安全,但它有效。它没有提供加盐机制,尽管我认为图书馆的其他地方对此有规定。

如果有人对如何让股票加密器在 heroku 上工作有任何想法,那么我认为这仍然是可取的。

于 2012-09-27T15:36:07.867 回答
0

您还可以执行以下操作。尽管这似乎已经停止在 Java 8 的最新版本上工作。

    Field field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
    if (Boolean.TRUE.equals(field.get(null))) {
        if (Modifier.isFinal(field.getModifiers())) {
            Field modifiers = Field.class.getDeclaredField("modifiers");
            modifiers.setAccessible(true);
            modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        }
        field.setAccessible(true);
        field.setBoolean(null, false); // isRestricted = false;
        field.setAccessible(false);
    }
    textEncryptor = Encryptors.text(key, salt);
于 2016-11-07T17:45:37.607 回答