微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决如何使用 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==)

有了这个,我可以轻松地执行第二个命令,我将获得原始值,即“测试”。

解密:

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"

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

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

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

解决方法

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

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

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

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

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

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

如果有人获得了您的计算机的访问权限,那将不再是您的计算机。使用 kubernetes secrets 或 Ansible vault、pipeline 参数……它可以帮助从代码库中分离秘密。

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

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

我的问题是你能不能以某种方式禁用 Jasypt 解密,以免获得实际价值,这样黑客也无法获得它?

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。