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 楼答案
这是不幸的提法。您可以加密数据(可逆)或哈希(不可逆)
事实上,有很多这样的问题,所以,只要搜索它。如果您有服务的秘密(例如DB凭据、API密钥),您可以对其进行加密,但您也需要在某个地方拥有密钥
这是从代码中分离秘密的最简单方法。你应该决定什么是威胁,你想保护什么以及如何保护。如果您限制了这种可能性,那么使用环境变量或部署参数将有助于减少源代码泄漏的可能性
如果有人进入你的电脑,那就不再是你的电脑了。使用kubernetes机密或Ansible vault,管道参数。。。它可以帮助从代码库中分离秘密
如果有人能模仿你或应用程序,你就无能为力了。这就是为什么您需要阻止它(最低权限、所有层上的安全性等等)
。。然后,您的应用程序也无法将其取回,应用程序将无法访问数据库或其他服务
可以选择不同的方式进行身份验证(例如Kerberos),但我个人会尽量避免这种情况,因为配置和故障排除并不简单。然后我们继续使用存储在环境或部署管道中某处的密码和密钥