有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用Jasypt进行安全加密?

在jasypt上。org关于问题“我可以解密加密密码吗?”它在这里说http://www.jasypt.org/faq.html#does-jasypt-implement-algorithms: “如果您使用消息摘要技术对其进行了加密,这正是您应该做的(通过使用PasswordEncryptor实现、StandardStringDigester或类似工具…)您不能。"

我必须说我试过各种方法,但在我看来,我总是有同样的问题。 我不知道为什么Jasypt让每个人都可以解密到原始值。例如,我可以轻松地对其进行加密,但也可以使用mvn命令对其进行解密:

使用jasypt进行加密和解密的示例:

加密:

mvn jasypt:encrypt-value -Djasypt.plugin.value="test" -Djasypt.encryptor.password="pass" -Djasypt.encryptor.algorithm="PBEWithMD5AndDES" -Djasypt.encryptor.key-obtention-iterations=1000 -Djasypt.encryptor.pool-size=1 -Djasypt.encryptor.provider-name="SunJCE" -Djasypt.encryptor.salt-generator-classname="org.jasypt.salt.RandomSaltGenerator" -Djasypt.encryptor.iv-generator-classname="org.jasypt.iv.NoIvGenerator" -Djasypt.encryptor.string-output-type="base64"

如您所见,在第一个命令中,我提供了要解密的值“test”和密码“pass”。 它生成:ENC(u7uKa3B9Xfey+zZ46tOmag==

有了它,我可以很容易地执行第二个命令,我将得到原始值,即“test”

解密:

mvn jasypt:decrypt-value -Djasypt.plugin.value="u7uKa3B9Xfey+zZ46tOmag==" -Djasypt.encryptor.password="pass" -Djasypt.encryptor.algorithm="PBEWithMD5AndDES" -Djasypt.encryptor.key-obtention-iterations=1000 -Djasypt.encryptor.pool-size=1 -Djasypt.encryptor.provider-name="SunJCE" -Djasypt.encryptor.salt-generator-classname="org.jasypt.salt.RandomSaltGenerator" -Djasypt.encryptor.iv-generator-classname="org.jasypt.iv.NoIvGenerator" -Djasypt.encryptor.string-output-type="base64"

在我的生活中。pom文件,我已经在依赖项部分中定义了:

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot</artifactId>
    <version>3.0.2</version>
</dependency>

还有这个内置部分(因此我可以通过maven执行jasypt):

<plugins>
    <plugin>
      <groupId>com.github.ulisesbocchio</groupId>
      <artifactId>jasypt-maven-plugin</artifactId>
      <version>3.0.2</version>
    </plugin>
<plugins>

我的应用程序yml如下所示:

jasypt:
    encryptor:
        password: pass
        algorithm: PBEWithMD5AndDES
        key-obtention-iterations: 1000
        pool-size: 1
        provider-name: SunJCE
        salt-generator-className: org.jasypt.salt.RandomSaltGenerator
        iv-generator-className: org.jasypt.iv.NoIvGenerator
        string-output-type: base64
        
spring:
  datasource:
    database-name: *****
    jdbc-url: *****
    username: *****
    password: ENC(u7uKa3B9Xfey+zZ46tOmag==)

一切都很好(我也通过java代码用bean尝试过,完全一样,只是风格不同)。但我为什么要这样做,让它保持这样,因为我知道黑客可以像我一样执行这个命令并获得实际价值:

他可以做到这一点,他拥有他所需要的一切——他可以从我的代码中阅读“u7uKa3B9Xfey+zZ46tOmag=”和“通过””: 解密:

mvn jasypt:decrypt-value -Djasypt.plugin.value="u7uKa3B9Xfey+zZ46tOmag==" -Djasypt.encryptor.password="pass" -Djasypt.encryptor.algorithm="PBEWithMD5AndDES" -Djasypt.encryptor.key-obtention-iterations=1000 -Djasypt.encryptor.pool-size=1 -Djasypt.encryptor.provider-name="SunJCE" -Djasypt.encryptor.salt-generator-classname="org.jasypt.salt.RandomSaltGenerator" -Djasypt.encryptor.iv-generator-classname="org.jasypt.iv.NoIvGenerator" -Djasypt.encryptor.string-output-type="base64"

他只需要阅读这个ENC(u7uKa3B9Xfey+zZ46tOmag==)(他可以从yml文件中读取,也可以从yml文件中读取“传递”(他也可以这样做)。就在这里,他可以找回最初的价值。我看不出这有什么安全性。黑客只需要知道如何执行mvn decrypt命令(在本例中我已经成功地做到了,为什么有人也不这么做),它基本上与加密相同

有人可能会说,‘好吧,您可以通过环境变量传递您的密码(“pass”)。不适合我。因为Gitlab和Dockerfile的两个文件都在项目中,如果我在那个里设置了这些变量,黑客仍然可以读取它们,并且在几秒钟内得到实际值。他们与我的项目有联系。此外,在Gitlab或Kubernetes等系统上提供实际密码(如环境变量)对我来说似乎非常危险。黑客,如果他是非常先进的,也可以阅读这些价值观。那为什么要揭露他们呢。这似乎是Jasypt唯一的解决方案,设置变量,比如APP_ENCRYPTION_PASSWORD

我的问题是,你能不能禁用Jasypt decrypt,这样就不会得到实际的价值,让黑客也无法得到它?对我来说,这似乎是最安全的选择。或者类似的解决方案来解决我的问题?如果可以,请提供一个例子Jasypt可以像生成盐一样,以某种方式动态生成密码,这将是一件好事,但是如何生成密码呢。我知道,那个么这个人应该动态地填充yml文件,这是不可能的。如果我只需要密码和加密值来解密原始值,我真的看不出Jasypt的安全性如何。这两个黑客都能读入源代码,在我看来,这似乎是非常糟糕的安全性。然后,在yml文件中屏蔽数据库密码的目的是什么。如果所有东西都能在几秒钟内打开。对我来说,这似乎是非常脆弱的安全。请告诉我如何使它比现在更安全


共 (1) 个答案

  1. # 1 楼答案

    "If you have encrypted it using a message digesting technique, ... you cannot."

    这是不幸的提法。您可以加密数据(可逆)或哈希(不可逆)

    事实上,有很多这样的问题,所以,只要搜索它。如果您有服务的秘密(例如DB凭据、API密钥),您可以对其进行加密,但您也需要在某个地方拥有密钥

    well, you can pass your password ("pass") through environment variable

    这是从代码中分离秘密的最简单方法。你应该决定什么是威胁,你想保护什么以及如何保护。如果您限制了这种可能性,那么使用环境变量或部署参数将有助于减少源代码泄漏的可能性

    Also, providing actual passwords like environmental variables on systems like Gitlab or Kubernetes seems very risky to me.

    如果有人进入你的电脑,那就不再是你的电脑了。使用kubernetes机密或Ansible vault,管道参数。。。它可以帮助从代码库中分离秘密

    Hacker, if he is very advanced, can read those values also.

    如果有人能模仿你或应用程序,你就无能为力了。这就是为什么您需要阻止它(最低权限、所有层上的安全性等等)

    My question is can you somehow disable Jasypt decrypt, in order not to get actual value back, so hacker can't also get to it?

    。。然后,您的应用程序也无法将其取回,应用程序将无法访问数据库或其他服务

    可以选择不同的方式进行身份验证(例如Kerberos),但我个人会尽量避免这种情况,因为配置和故障排除并不简单。然后我们继续使用存储在环境或部署管道中某处的密码和密钥