java - 如何保护 TextEncryptor 在 spring boot 中使用的密码

标签 java spring security encryption spring-boot

我需要为我的应用程序的用户加密一些细节(不是密码,我为此使用 bcrypt),我需要在将来的某个时候访问细节,所以我需要能够解密这些细节,为此,我的 spring boot 应用程序中有以下类,我的问题是如何保护用于加密文本的密码?

import org.springframework.security.crypto.encrypt.Encryptors;
import org.springframework.security.crypto.encrypt.TextEncryptor;

public class Crypto 
{

 final static String password = "How_to_Secure_This_Password?";  

 public static String encrypt(String textToEncrypt, String salt) 
 {
    if (textToEncrypt != null && !textToEncrypt.isEmpty())
    {
        TextEncryptor encryptor = Encryptors.text(password, salt);   
        String encryptedText = encryptor.encrypt(textToEncrypt);
        return encryptedText;
    }

    return null;

 }

 public static String decrypt(String encryptedText, String salt) 
 {
    if(encryptedText != null && !encryptedText.isEmpty())
    {
        TextEncryptor decryptor = Encryptors.text(password, salt);
        String decryptedText = decryptor.decrypt(encryptedText);

        return decryptedText;
    }

    return null;

 }
}

根据我目前的研究,我可以提出以下解决方案:

1- 从属性文件中获取密码并使用 Spring Cloud Config 为属性文件加密/解密功能(值以字符串 {cipher} 为前缀),一个好的起点是 here .我不喜欢这个解决方案,因为我不需要客户端/服务器配置结构,而且我不喜欢仅仅为了一个特性而使用它,我相信 Spring 框架应该具有类似的特性。

2- 使用 Jasypt库,或其对来自 here 的 spring boot 的“非官方”支持.同样,不确定问题是否与在属性文件中加密此密码有关?

3- 使用 Vault它看起来是为类似于我在这里需要的东西(API key 、 secret 等...)构建的,但构建、维护和集成的开销太大...

我在这里的论点是,如果攻击者能够访问我的数据库机器,那么他很可能将能够访问应用程序机器,这意味着他可能能够对类进行逆向工程,并将能够解密我想要保护的所有细节!我在这里感到困惑,这里的最佳实践和行业标准是什么?

最佳答案

目前最好的解决方案是使用 Spring Cloud Vault因为我已经在使用 spring boot,它可以提供的不仅仅是保护这个密码,事实上它可以保护许多 API key 、数据库等的密码(在撰写本文时它是 RC 版本)..然而,我不相信然而这是最终的解决方案,因为我的应用程序仍然需要针对 Vault 进行身份验证,但我不得不说这是以更高级的方式完成的,并且比将密码保存在配置文件中更进一步......

这个问题是先有鸡还是先有蛋的问题,事实证明 SO 对于类似的场景有很多类似的问题(在配置中保存数据库密码,在代码中隐藏它,在 PBE 存储中隐藏密码等等)。

Mark Paluch 在他的入门指南中很好地解释了这一点 article

Encrypted data is one step better than unencrypted. Encryption imposes on the other side the need for decryption on the user side which requires a decryption key to be distributed. Now, where do you put the key? Is the key protected by a passphrase? Where do you put the passphrase? On how many systems do you distribute your key and the passphrase?

As you see, encryption introduces a chicken-egg problem. Storing a decryption key gives the application the possibility to decrypt data. It also allows an attack vector. Someone who is not authorized could get access to the decryption key by having access to the machine. That person can decrypt data which is decryptable by this key. The key is static so a leaked key requires the change of keys. Data needs to be re-encrypted and credentials need to be changed. It’s not possible to discover such leakage with online measure because data can be decrypted offline once it was obtained.

.......

Vault isn’t the answer for all security concern. It’s worth to check the Vault Security Model documentation to get an idea of the threat model.

具有讽刺意味的是,Vault storage backend在大多数情况下需要配置纯文本密码(MySQL、S3、Azure ......我还没有接受这个作为我问题的答案,但这是我到目前为止所发现的,等待其他人的更多输入非常感谢贡献者!

关于java - 如何保护 TextEncryptor 在 spring boot 中使用的密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43174760/

相关文章:

java - 如何阻止输入中的负值存储在数组中?

java - onclick 我想获取 JFrame 上存在的 JPanel 的名称

ios - 通过应用内购买验证收据

security - SSL 证书和 cURL : certificate bundle or untrusted certificate?

web-services - 如果 IIS 中的 SSL 设置设置为忽略或仅接受,SSL 是否仍然安全?

java - SwingWorker 中的类型参数有哪些?

java - 如何将后端(Mysql)的表显示到前端Net-Beans?

java - Spring 4 - websocket消息stomp处理程序

java - Spring batch JdbcPagingItemReader 未正确初始化,因为它未正确关闭

java - Cometd 发布输入数据 Map 而不是等待服务器的输出