【问题标题】:How to make safe encryption with Jasypt?如何使用 Jasypt 进行安全加密?
【发布时间】:2021-09-13 13:52:36
【问题描述】:

关于问题“我可以解密加密密码吗?”在 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==”和“pass”: 解密:

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"

他只需要从 yml 文件中读取这个 ENC(u7uKa3B9Xfey+zZ46tOmag==)(他可以从 yml 文件中读取,并且也可以从 yml 文件中“pass”(他也可以这样做)。就是这样,他可以取回原始值。我没有看到任何安全性。黑客只需要知道如何执行 mvn 解密命令(我已经设法在这个这里做到了)例如,为什么有人不设法也这样做),它与加密基本相同。

有人可能会争辩说,'好吧,你可以通过环境变量传递你的密码(“pass”)'。对我不起作用。因为 Gitlab 和 Dockerfile 的两个文件,我都在项目中,如果我在那里设置这些变量,黑客仍然可以读取它并在几秒钟内获得实际值。它们绑定到我的项目。此外,在 Gitlab 或 Kubernetes 等系统上提供环境变量等实际密码对我来说似乎非常冒险。黑客,如果他非常先进,也可以读取这些值。那为什么要暴露他们。似乎这是 Jasypt 的唯一解决方案,设置像 APP_ENCRYPTION_PASSWORD 这样的变量。

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

【问题讨论】:

    标签: java spring spring-boot encryption jasypt


    【解决方案1】:

    “如果您使用消息摘要技术对其进行了加密,……您不能。”

    这是不幸的表述。您可以加密数据(可逆)或散列(不可逆)。

    其实SO上有很多这样的问题,随便搜一下。如果您有服务的秘密(例如数据库凭据、API 密钥),您可以对其进行加密,但您也需要在某处拥有密钥。

    嗯,你可以通过环境变量传递你的密码(“pass”)

    这是从代码中分离秘密的最简单方法。您应该决定什么是威胁,您要防范什么以及如何防范。如果您限制了机密信息会随源代码泄漏的可能性,则使用环境变量或部署参数可能会有所帮助。

    此外,在 Gitlab 或 Kubernetes 等系统上提供环境变量等实际密码对我来说似乎非常冒险。

    如果有人获得了对您计算机的访问权限,那将不再是您的计算机。使用 kubernetes 机密或 Ansible 保险库、管道参数……它可以帮助将机密与您的代码库分开。

    黑客,如果他非常先进,也可以读取这些值。

    如果有人可以冒充您或该应用程序,您将无能为力。这就是为什么您需要阻止它(最低权限、所有层的安全性......)

    我的问题是,你能否以某种方式禁用 Jasypt 解密,以免收回实际价值,让黑客也无法得到它?

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

    有一些选项可以通过不同的方式进行身份验证(例如 Kerberos),但我个人尽量避免使用它,因为配置和故障排除并不简单。然后我们保留存储在环境或部署管道中某处的密码和密钥。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多