Spring boot 2.x 和 3.0.0 的Jasypt集成
Jasypt Spring Boot 为 Spring Boot 应用程序中的属性源提供加密支持。
有 3 种方法可以将jasypt-spring-boot
集成到您的项目中:
@SpringBootApplication
或@EnableAutoConfiguration
只需将启动器 jar jasypt-spring-boot-starter
添加到类路径即可在整个 Spring 环境中启用可加密属性jasypt-spring-boot
添加到类路径并将@EnableEncryptableProperties
添加到主 Configuration 类,以在整个 Spring 环境中启用可加密属性jasypt-spring-boot
添加到类路径并使用@EncrytablePropertySource
声明单独的可加密属性源使用以下 3 种方法之一(上面已简要说明):
如果您的 Spring Boot 应用程序使用@SpringBootApplication
或@EnableAutoConfiguration
,则只需将启动器 jar 依赖项添加到您的项目中,并且将在整个 Spring 环境中启用可加密属性(这意味着任何系统属性、环境属性、命令行参数、application.properties、application -*.properties、yaml 属性和任何其他属性源都可以包含加密属性):
< dependency >
< groupId >com.github.ulisesbocchio</ groupId >
< artifactId >jasypt-spring-boot-starter</ artifactId >
< version >3.0.5</ version >
</ dependency >
如果您不使用@SpringBootApplication
或@EnableAutoConfiguration
自动配置注释,则将此依赖项添加到您的项目中:
< dependency >
< groupId >com.github.ulisesbocchio</ groupId >
< artifactId >jasypt-spring-boot</ artifactId >
< version >3.0.5</ version >
</ dependency >
然后将@EnableEncryptableProperties
添加到您的 Configuration 类中。例如:
@ Configuration
@ EnableEncryptableProperties
public class MyApplication {
...
}
并且将在整个 Spring 环境中启用可加密属性(这意味着任何系统属性、环境属性、命令行参数、application.properties、yaml 属性和任何其他自定义属性源都可以包含加密属性)
如果您不使用@SpringBootApplication
或@EnableAutoConfiguration
自动配置注释,并且您不想在整个 Spring 环境中启用可加密属性,那么还有第三种选择。首先将以下依赖项添加到您的项目中:
< dependency >
< groupId >com.github.ulisesbocchio</ groupId >
< artifactId >jasypt-spring-boot</ artifactId >
< version >3.0.5</ version >
</ dependency >
然后在配置文件中添加任意数量的@EncryptablePropertySource
注释。就像使用 Spring 的@PropertySource
注释一样。例如:
@ Configuration
@ EncryptablePropertySource ( name = "EncryptedProperties" , value = "classpath:encrypted.properties" )
public class MyApplication {
...
}
方便的是,还有一个@EncryptablePropertySources
注释,可以用来对@EncryptablePropertySource
类型的注释进行分组,如下所示:
@ Configuration
@ EncryptablePropertySources ({ @ EncryptablePropertySource ( "classpath:encrypted.properties" ),
@ EncryptablePropertySource ( "classpath:encrypted2.properties" )})
public class MyApplication {
...
}
另请注意,从版本 1.8 开始, @EncryptablePropertySource
支持 YAML 文件
截至版本1.7 1.15 中,对于某些特殊情况,存在启用可加密属性的第四种方法。提供了自定义ConfigurableEnvironment
类: EncryptableEnvironment
StandardEncryptableEnvironment
和StandardEncryptableServletEnvironment
可以与SpringApplicationBuilder
一起使用,以这种方式定义自定义环境:
new SpringApplicationBuilder ()
. environment ( new StandardEncryptableEnvironment ())
. sources ( YourApplicationClass . class ). run ( args );
此方法只需要使用jasypt-spring-boot
的依赖项。不需要启动程序 jar 依赖项。此方法对于引导程序上的加密属性的早期访问很有用。虽然在大多数情况下不需要,但在自定义 Spring Boot 的 init 行为或与早期配置的某些功能(例如日志配置)集成时可能会很有用。举一个具体的例子,这种启用可加密属性的方法是唯一一种可以使用springProperty
标签在logback-spring.xml
文件中替换 Spring Properties 的方法。例如:
< springProperty name = " user " source = " db.user " />
< springProperty name = " password " source = " db.password " />
< appender name = " db " class = " ch.qos.logback.classic.db.DBAppender " >
< connectionSource
class = " ch.qos.logback.core.db.DriverManagerConnectionSource " >
< driverClass >org.postgresql.Driver</ driverClass >
< url >jdbc:postgresql://localhost:5432/simple</ url >
< user >${user}</ user >
< password >${password}</ password >
</ connectionSource >
</ appender >
例如,可以使用此机制(如图所示)来初始化需要传递敏感凭据的数据库日志记录附加程序。或者,如果需要提供自定义StringEncryptor
,则提供静态构建器方法StandardEncryptableEnvironment#builder
进行自定义(也可以进行其他自定义):
StandardEncryptableEnvironment
. builder ()
. encryptor ( new MyEncryptor ())
. build ()
这将触发一些配置的加载,这些配置基本上做了两件事:
StringEncryptor
,可以通过常规属性、系统属性或命令行参数进行配置。 使用方法 1 和 2 时,您可以在环境中包含的任何 PropertySource 中定义加密属性。例如,使用@PropertySource注释:
@ SpringBootApplication
@ EnableEncryptableProperties
@ PropertySource ( name = "EncryptedProperties" , value = "classpath:encrypted.properties" )
public class MyApplication {
...
}
你的 crypto.properties 文件看起来像这样:
secret.property =ENC(nrmZtkF7T0kjG/VodDvBw93Ct8EgjCA+)
现在,当您执行environment.getProperty("secret.property")
或使用@Value("${secret.property}")
时,您得到的是secret.property
的解密版本。
当使用方法3( @EncryptablePropertySource
)时,您可以以相同的方式访问加密的属性,唯一的区别是您必须将属性放在@EncryptablePropertySource
注释中声明的资源中,以便可以正确解密属性。
Jasypt 使用StringEncryptor
来解密属性。对于所有 3 种方法,如果在 Spring 上下文中找不到自定义StringEncryptor
(详细信息请参阅自定义加密器部分),则会自动创建一个可以通过以下属性(系统、属性文件、命令行参数、环境变量、 ETC。):
钥匙 | 必需的 | 默认值 |
jasypt.加密器.密码 | 真的 | - |
jasypt.加密器.算法 | 错误的 | PBEWITHHMACSHA512ANDAES_256 |
jasypt.cryptor.key-obtention-iterations | 错误的 | 1000 |
jasypt.加密器.池大小 | 错误的 | 1 |
jasypt.cryptor.provider-name | 错误的 | 太阳JCE |
jasypt.cryptor.provider-class-name | 错误的 | 无效的 |
jasypt.cryptor.salt-generator-classname | 错误的 | org.jasypt.salt.RandomSaltGenerator |
jasypt.cryptor.iv-生成器-类名 | 错误的 | org.jasypt.iv.RandomIvGenerator |
jasypt.cryptor.字符串输出类型 | 错误的 | 64位基数 |
jasypt.cryptor.proxy-property-sources | 错误的 | 错误的 |
jasypt.cryptor.skip-property-sources | 错误的 | 空列表 |
唯一需要的属性是加密密码,其余的可以保留使用默认值。虽然所有这些属性都可以在属性文件中声明,但加密器密码不应存储在属性文件中,而应作为系统属性、命令行参数或环境变量传递,并且只要其名称为jasypt.encryptor.password
就可以了。
最后一个属性jasypt.encryptor.proxyPropertySources
用于指示jasyp-spring-boot
如何拦截属性值以进行解密。默认值false
使用PropertySource
、 EnumerablePropertySource
和MapPropertySource
的自定义包装器实现。当为此属性指定true
时,拦截机制将在每个特定PropertySource
实现上使用 CGLib 代理。这在某些必须保留原始PropertySource
类型的场景中可能很有用。
对于加密器的自定义配置和加密器密码的来源,您始终可以在 Spring 上下文中定义自己的 StringEncryptor bean,并且默认的加密器将被忽略。例如:
@ Bean ( "jasyptStringEncryptor" )
public StringEncryptor stringEncryptor () {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor ();
SimpleStringPBEConfig config = new SimpleStringPBEConfig ();
config . setPassword ( "password" );
config . setAlgorithm ( "PBEWITHHMACSHA512ANDAES_256" );
config . setKeyObtentionIterations ( "1000" );
config . setPoolSize ( "1" );
config . setProviderName ( "SunJCE" );
config . setSaltGeneratorClassName ( "org.jasypt.salt.RandomSaltGenerator" );
config . setIvGeneratorClassName ( "org.jasypt.iv.RandomIvGenerator" );
config . setStringOutputType ( "base64" );
encryptor . setConfig ( config );
return encryptor ;
}
请注意,bean 名称是必需的,因为jasypt-spring-boot
从版本1.5
开始按名称检测自定义字符串加密器。默认的 bean 名称是:
jasyptStringEncryptor
但也可以通过定义属性来覆盖这一点:
jasypt.encryptor.bean
例如,如果您定义jasypt.encryptor.bean=encryptorBean
那么您将使用该名称定义自定义加密器:
@ Bean ( "encryptorBean" )
public StringEncryptor stringEncryptor () {
...
}
从jasypt-spring-boot-1.10
开始,有新的扩展点。 EncryptablePropertySource
现在使用EncryptablePropertyResolver
来解析所有属性:
public interface EncryptablePropertyResolver {
String resolvePropertyValue ( String value );
}
该接口的实现负责检测和解密属性。默认实现DefaultPropertyResolver
使用前面提到的StringEncryptor
和新的EncryptablePropertyDetector
。
EncryptablePropertyDetector
您可以通过提供名称为encryptablePropertyDetector
的EncryptablePropertyDetector
类型的 Bean 来覆盖默认实现,或者如果您想提供自己的 bean 名称,请覆盖属性jasypt.encryptor.property.detector-bean
并指定您想要为该 bean 指定的名称。提供此信息时,您将负责检测加密的属性。例子:
private static class MyEncryptablePropertyDetector implements EncryptablePropertyDetector {
@ Override
public boolean isEncrypted ( String value ) {
if ( value != null ) {
return value . startsWith ( "ENC@" );
}
return false ;
}
@ Override
public String unwrapEncryptedValue ( String value ) {
return value . substring ( "ENC@" . length ());
}
}
@ Bean ( name = "encryptablePropertyDetector" )
public EncryptablePropertyDetector encryptablePropertyDetector () {
return new MyEncryptablePropertyDetector ();
}
prefix
和suffix
如果您只想为加密属性使用不同的前缀/后缀,则可以继续使用所有默认实现,只需覆盖application.properties
(或application.yml
)中的以下属性:
jasypt :
encryptor :
property :
prefix : " ENC@[ "
suffix : " ] "
EncryptablePropertyResolver
您可以通过提供名称为encryptablePropertyResolver
的EncryptablePropertyResolver
类型的 Bean 来覆盖默认实现,或者如果您想提供自己的 bean 名称,请覆盖属性jasypt.encryptor.property.resolver-bean
并指定您想要为该 bean 指定的名称。提供此信息时,您将负责检测和解密加密的属性。例子:
class MyEncryptablePropertyResolver implements EncryptablePropertyResolver {
private final PooledPBEStringEncryptor encryptor ;
public MyEncryptablePropertyResolver ( char [] password ) {
this . encryptor = new PooledPBEStringEncryptor ();
SimpleStringPBEConfig config = new SimpleStringPBEConfig ();
config . setPasswordCharArray ( password );
config . setAlgorithm ( "PBEWITHHMACSHA512ANDAES_256" );
config . setKeyObtentionIterations ( "1000" );
config . setPoolSize ( 1 );
config . setProviderName ( "SunJCE" );
config . setSaltGeneratorClassName ( "org.jasypt.salt.RandomSaltGenerator" );
config . setIvGeneratorClassName ( "org.jasypt.iv.RandomIvGenerator" );
config . setStringOutputType ( "base64" );
encryptor . setConfig ( config );
}
@ Override
public String resolvePropertyValue ( String value ) {
if ( value != null && value . startsWith ( "{cipher}" )) {
return encryptor . decrypt ( value . substring ( "{cipher}" . length ()));
}
return value ;
}
}
@ Bean ( name = "encryptablePropertyResolver" )
EncryptablePropertyResolver encryptablePropertyResolver ( @ Value ( "${jasypt.encryptor.password}" ) String password ) {
return new MyEncryptablePropertyResolver ( password . toCharArray ());
}
请注意,通过覆盖EncryptablePropertyResolver
,您可能对前缀、后缀、 EncryptablePropertyDetector
和StringEncryptor
进行的任何其他配置或覆盖都将停止工作,因为默认解析器是使用它们的。你必须自己接线所有这些东西。幸运的是,在大多数情况下您不必重写此 bean,前面的选项就足够了。
但正如您在实现中看到的,加密属性的检测和解密是MyEncryptablePropertyResolver
内部的
jasypt-spring-boot:2.1.0
引入了一个新功能来指定属性过滤器。该过滤器是EncryptablePropertyResolver
API 的一部分,允许您确定要考虑解密的属性或属性源。这是在检查实际属性值以搜索或尝试解密它之前。例如,默认情况下,名称以jasypt.encryptor
开头的所有属性都会被排除在检查之外。这是为了避免在配置库 bean 时加载时出现循环依赖关系。
默认情况下, DefaultPropertyResolver
使用DefaultPropertyFilter
,它允许您指定以下字符串模式列表:
EncryptablePropertyFilter
您可以通过提供名称为encryptablePropertyFilter
的EncryptablePropertyFilter
类型的 Bean 来覆盖默认实现,或者如果您想提供自己的 bean 名称,请覆盖属性jasypt.encryptor.property.filter-bean
并指定您想要为该 bean 指定的名称。提供此信息时,您将负责检测要考虑解密的属性和/或属性源。例子:
class MyEncryptablePropertyFilter implements EncryptablePropertyFilter {
public boolean shouldInclude ( PropertySource <?> source , String name ) {
return name . startsWith ( 'encrypted.' );
}
}
@ Bean ( name = "encryptablePropertyFilter" )
EncryptablePropertyFilter encryptablePropertyFilter () {
return new MyEncryptablePropertyFilter ();
}
请注意,要使此机制发挥作用,您不应提供自定义EncryptablePropertyResolver
,而应使用默认解析器。如果您提供自定义解析器,则您负责检测和解密属性的整个过程。
PropertySource
类以免被内省定义要在自省中跳过的完全限定类名的逗号分隔列表。该类不会被该插件包装/代理,因此其中包含的属性不支持加密/解密:
jasypt.encryptor.skip-property-sources =org.springframework.boot.env.RandomValuePropertySource,org.springframework.boot.ansi.AnsiPropertySource
加密的属性缓存在您的应用程序中,在某些情况下,例如使用来自配置服务器的外部化配置时,属性发生更改时需要刷新。为此, jasypt-spring-boot
注册了一个RefreshScopeRefreshedEventListener
,默认监听以下事件以清除加密属性缓存:
public static final List < String > EVENT_CLASS_NAMES = Arrays . asList (
"org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent" ,
"org.springframework.cloud.context.environment.EnvironmentChangeEvent" ,
"org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent"
);
如果您需要注册额外的事件来触发加密的缓存失效,您可以使用以下属性添加它们(如果需要多个,则用逗号分隔):
jasypt.encryptor.refreshed-event-classes =org.springframework.boot.context.event.ApplicationStartedEvent
Maven 插件提供了许多有用的实用程序。
要使用该插件,只需将以下内容添加到您的 pom.xml 中:
< build >
< plugins >
< plugin >
< groupId >com.github.ulisesbocchio</ groupId >
< artifactId >jasypt-maven-plugin</ artifactId >
< version >3.0.5</ version >
</ plugin >
</ plugins >
</ build >
使用此插件时,提供加密密码的最简单方法是通过系统属性,即-Djasypt.encryptor.password =“密码”。
默认情况下,该插件将考虑 ./src/main/resources 下标准 Spring boot 配置文件中的加密配置。您还可以使用系统属性或环境变量来提供此配置。
请记住,您的应用程序代码和资源的其余部分不可用于该插件,因为 Maven 插件不与项目共享类路径。如果您的应用程序通过 StringEncryptor bean 提供加密配置,则不会选择该配置。
一般来说,建议仅依赖安全的默认配置。
要加密单个值,请运行:
mvn jasypt:encrypt-value -Djasypt.encryptor.password= " the password " -Djasypt.plugin.value= " theValueYouWantToEncrypt "
要加密src/main/resources/application.properties
中的占位符,只需用DEC(...)
包装任何字符串即可。例如:
sensitive.password =DEC(secret value)
regular.property =example
然后运行:
mvn jasypt:encrypt -Djasypt.encryptor.password= " the password "
这将就地编辑该文件,导致:
sensitive.password =ENC(encrypted)
regular.property =example
文件名和位置可以自定义。
要解密单个值,请运行:
mvn jasypt:decrypt-value -Djasypt.encryptor.password= " the password " -Djasypt.plugin.value= " DbG1GppXOsFa2G69PnmADvQFI3esceEhJYbaEIKCcEO5C85JEqGAhfcjFMGnoRFf "
要解密src/main/resources/application.properties
中的占位符,只需用ENC(...)
包装任何字符串。例如:
sensitive.password =ENC(encrypted)
regular.property =example
可以按如下方式解密:
mvn jasypt:decrypt -Djasypt.encryptor.password= " the password "
这会将解密的内容输出到屏幕上:
sensitive.password =DEC(decrypted)
regular.property =example
请注意,输出到屏幕,而不是就地编辑文件,旨在减少将解密值意外提交到版本控制的情况。解密时,您很可能只想检查已加密的值,而不是想要永久解密该值。
使用加密/解密目标更改现有加密属性的配置有点尴尬。您必须使用旧配置运行解密目标,然后将解密的输出复制回原始文件,然后使用新配置运行加密目标。
重新加密目标通过就地重新加密文件来简化这一过程。必须提供2套配置。新配置的提供方式与配置其他 Maven 目标的方式相同。旧配置是通过前缀为“jasypt.plugin.old”而不是“jasypt.encryptor”的系统属性提供的。
例如,要重新加密之前使用密码 OLD 加密的 application.properties,然后使用新密码 NEW 加密:
mvn jasypt:reencrypt -Djasypt.plugin.old.password=OLD -Djasypt.encryptor.password=NEW
注意:所有旧配置必须作为系统属性传递。不支持环境变量和 Spring Boot 配置文件。
有时,默认加密配置可能会在 jasypt-spring-boot 版本之间发生变化。您可以根据升级目标自动将加密属性升级到新的默认值。这将使用旧的默认配置解密您的 application.properties 文件,并使用新的默认配置重新加密。
mvn jasypt:upgrade -Djasypt.encryptor.password=EXAMPLE
您还可以传递系统属性-Djasypt.plugin.old.major-version
来指定要升级的版本。这将始终默认为配置更改的最后一个主要版本。目前,唯一更改默认值的主要版本是版本 2,因此无需设置此属性,但它可供将来使用。
您还可以解密属性文件并将其所有属性加载到内存中并使 Maven 可以访问它们。当您想要使加密属性可供其他 Maven 插件使用时,这非常有用。
您可以将后续插件的目标直接链接到此插件之后。例如,对于飞行路线:
mvn jasypt:load flyway:migrate -Djasypt.encryptor.password= " the password "
您还可以使用-Djasypt.plugin.keyPrefix=example.
。这有助于避免与其他 Maven 属性发生潜在冲突。
对于上述所有实用程序,您要加密/解密的文件的路径默认为file:src/main/resources/application.properties
。
这可以使用-Djasypt.plugin.path
系统属性进行更改。
您可以加密测试资源目录中的文件:
mvn jasypt:encrypt -Djasypt.plugin.path= " file:src/main/test/application.properties " -Djasypt.encryptor.password= " the password "
或者使用不同的名称:
mvn jasypt:encrypt -Djasypt.plugin.path= " file:src/main/resources/flyway.properties " -Djasypt.encryptor.password= " the password "
或者使用不同的文件类型(该插件支持任何纯文本文件格式,包括 YAML):
mvn jasypt:encrypt -Djasypt.plugin.path= " file:src/main/resources/application.yaml " -Djasypt.encryptor.password= " the password "
请注意,加载目标仅支持 .property 文件
运行插件时,您可以覆盖应用程序中支持的任何 spring 配置,例如选择给定的 spring 配置文件:
mvn jasypt:encrypt -Dspring.profiles.active=cloud -Djasypt.encryptor.password= " the password "
要加密/解密多模块项目中的属性,请在 maven 命令上使用-N
或--non-recursive
禁用递归:
mvn jasypt:upgrade -Djasypt.plugin.path=file:server/src/test/resources/application-test.properties -Djasypt.encryptor.password=supersecret -N
jasypt-spring-boot:2.1.1
引入了一项新功能,使用非对称加密和一对 DER 或 PEM 格式的私钥/公钥来加密/解密属性。
以下是可用于配置属性的非对称解密的配置属性;
钥匙 | 默认值 | 描述 |
jasypt.cryptor.privateKeyString | 无效的 | 用于解密的字符串格式的私钥 |
jasypt.cryptor.privateKeyLocation | 无效的 | spring 资源格式中用于解密的私钥的位置 |
jasypt.cryptor.privateKeyFormat | 德 | 密钥格式。 DER 或 PEM |
您应该使用privateKeyString
或privateKeyLocation
,如果设置,则字符串格式优先。要使用privateKeyString
指定 DER 格式的私钥,请将密钥字节编码为base64
。
请注意,对于 PBE 加密, jasypt.encryptor.password
仍然优先于非对称配置。
jasypt :
encryptor :
privateKeyString: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCtB/IYK8E52CYMZTpyIY9U0HqMewyKnRvSo6s+9VNIn/HSh9+MoBGiADa2MaPKvetS3CD3CgwGq/+LIQ1HQYGchRrSORizOcIp7KBx+Wc1riatV/tcpcuFLC1j6QJ7d2I+T7RA98Sx8X39orqlYFQVysTw/aTawX/yajx0UlTW3rNAY+ykeQ0CBHowtTxKM9nGcxLoQbvbYx1iG9JgAqye7TYejOpviOH+BpD8To2S8zcOSojIhixEfayay0gURv0IKJN2LP86wkpAuAbL+mohUq1qLeWdTEBrIRXjlnrWs1M66w0l/6JwaFnGOqEB6haMzE4JWZULYYpr2yKyoGCRAgMBAAECggEAQxURhs1v3D0wgx27ywO3zeoFmPEbq6G9Z6yMd5wk7cMUvcpvoNVuAKCUlY4pMjDvSvCM1znN78g/CnGF9FoxJb106Iu6R8HcxOQ4T/ehS+54kDvL999PSBIYhuOPUs62B/Jer9FfMJ2veuXb9sGh19EFCWlMwILEV/dX+MDyo1qQaNzbzyyyaXP8XDBRDsvPL6fPxL4r6YHywfcPdBfTc71/cEPksG8ts6um8uAVYbLIDYcsWopjVZY/nUwsz49xBCyRcyPnlEUJedyF8HANfVEO2zlSyRshn/F+rrjD6aKBV/yVWfTEyTSxZrBPl4I4Tv89EG5CwuuGaSagxfQpAQKBgQDXEe7FqXSaGk9xzuPazXy8okCX5pT6545EmqTP7/JtkMSBHh/xw8GPp+JfrEJEAJJl/ISbdsOAbU+9KAXuPmkicFKbodBtBa46wprGBQ8XkR4JQoBFj1SJf7Gj9ozmDycozO2Oy8a1QXKhHUPkbPQ0+w3efwoYdfE67ZodpFNhswKBgQDN9eaYrEL7YyD7951WiK0joq0BVBLK3rwO5+4g9IEEQjhP8jSo1DP+zS495t5ruuuuPsIeodA79jI8Ty+lpYqqCGJTE6muqLMJDiy7KlMpe0NZjXrdSh6edywSz3YMX1eAP5U31pLk0itMDTf2idGcZfrtxTLrpRffumowdJ5qqwKBgF+XZ+JRHDN2aEM0atAQr1WEZGNfqG4Qx4o0lfaaNs1+H+knw5kIohrAyvwtK1LgUjGkWChlVCXb8CoqBODMupwFAqKL/IDImpUhc/t5uiiGZqxE85B3UWK/7+vppNyIdaZL13a1mf9sNI/p2whHaQ+3WoW/P3R5z5uaifqM1EbDAoGAN584JnUnJcLwrnuBx1PkBmKxfFFbPeSHPzNNsSK3ERJdKOINbKbaX+7DlT4bRVbWvVj/jcw/c2Ia0QTFpmOdnivjefIuehffOgvU8rsMeIBsgOvfiZGx0TP3+CCFDfRVqjIBt3HAfAFyZfiP64nuzOERslL2XINafjZW5T0pZz8CgYAJ3UbEMbKdvIuK+uTl54R1Vt6FO9T5bgtHR4luPKoBv1ttvSC6BlalgxA0Ts/AQ9tCsUK2JxisUcVgMjxBVvG0lfq/EHpL0Wmn59SHvNwtHU2qx3Ne6M0nQtneCCfR78OcnqQ7+L+3YCMqYGJHNFSard+dewfKoPnWw0WyGFEWCg==
jasypt :
encryptor :
privateKeyLocation : classpath:private_key.der
jasypt :
encryptor :
privateKeyFormat : PEM
privateKeyString : |-
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCtB/IYK8E52CYM
ZTpyIY9U0HqMewyKnRvSo6s+9VNIn/HSh9+MoBGiADa2MaPKvetS3CD3CgwGq/+L
IQ1HQYGchRrSORizOcIp7KBx+Wc1riatV/tcpcuFLC1j6QJ7d2I+T7RA98Sx8X39
orqlYFQVysTw/aTawX/yajx0UlTW3rNAY+ykeQ0CBHowtTxKM9nGcxLoQbvbYx1i
G9JgAqye7TYejOpviOH+BpD8To2S8zcOSojIhixEfayay0gURv0IKJN2LP86wkpA
uAbL+mohUq1qLeWdTEBrIRXjlnrWs1M66w0l/6JwaFnGOqEB6haMzE4JWZULYYpr
2yKyoGCRAgMBAAECggEAQxURhs1v3D0wgx27ywO3zeoFmPEbq6G9Z6yMd5wk7cMU
vcpvoNVuAKCUlY4pMjDvSvCM1znN78g/CnGF9FoxJb106Iu6R8HcxOQ4T/ehS+54
kDvL999PSBIYhuOPUs62B/Jer9FfMJ2veuXb9sGh19EFCWlMwILEV/dX+MDyo1qQ
aNzbzyyyaXP8XDBRDsvPL6fPxL4r6YHywfcPdBfTc71/cEPksG8ts6um8uAVYbLI
DYcsWopjVZY/nUwsz49xBCyRcyPnlEUJedyF8HANfVEO2zlSyRshn/F+rrjD6aKB
V/yVWfTEyTSxZrBPl4I4Tv89EG5CwuuGaSagxfQpAQKBgQDXEe7FqXSaGk9xzuPa
zXy8okCX5pT6545EmqTP7/JtkMSBHh/xw8GPp+JfrEJEAJJl/ISbdsOAbU+9KAXu
PmkicFKbodBtBa46wprGBQ8XkR4JQoBFj1SJf7Gj9ozmDycozO2Oy8a1QXKhHUPk
bPQ0+w3efwoYdfE67ZodpFNhswKBgQDN9eaYrEL7YyD7951WiK0joq0BVBLK3rwO
5+4g9IEEQjhP8jSo1DP+zS495t5ruuuuPsIeodA79jI8Ty+lpYqqCGJTE6muqLMJ
Diy7KlMpe0NZjXrdSh6edywSz3YMX1eAP5U31pLk0itMDTf2idGcZfrtxTLrpRff
umowdJ5qqwKBgF+XZ+JRHDN2aEM0atAQr1WEZGNfqG4Qx4o0lfaaNs1+H+knw5kI
ohrAyvwtK1LgUjGkWChlVCXb8CoqBODMupwFAqKL/IDImpUhc/t5uiiGZqxE85B3
UWK/7+vppNyIdaZL13a1mf9sNI/p2whHaQ+3WoW/P3R5z5uaifqM1EbDAoGAN584
JnUnJcLwrnuBx1PkBmKxfFFbPeSHPzNNsSK3ERJdKOINbKbaX+7DlT4bRVbWvVj/
jcw/c2Ia0QTFpmOdnivjefIuehffOgvU8rsMeIBsgOvfiZGx0TP3+CCFDfRVqjIB
t3HAfAFyZfiP64nuzOERslL2XINafjZW5T0pZz8CgYAJ3UbEMbKdvIuK+uTl54R1
Vt6FO9T5bgtHR4luPKoBv1ttvSC6BlalgxA0Ts/AQ9tCsUK2JxisUcVgMjxBVvG0
lfq/EHpL0Wmn59SHvNwtHU2qx3Ne6M0nQtneCCfR78OcnqQ7+L+3YCMqYGJHNFSa
rd+dewfKoPnWw0WyGFEWCg==
-----END PRIVATE KEY-----
jasypt :
encryptor :
privateKeyFormat : PEM
privateKeyLocation : classpath:private_key.pem
没有程序/命令可以使用非对称密钥加密属性,但您可以使用以下代码片段来加密您的属性:
import com . ulisesbocchio . jasyptspringboot . encryptor . SimpleAsymmetricConfig ;
import com . ulisesbocchio . jasyptspringboot . encryptor . SimpleAsymmetricStringEncryptor ;
import org . jasypt . encryption . StringEncryptor ;
public class PropertyEncryptor {
public static void main ( String [] args ) {
SimpleAsymmetricConfig config = new SimpleAsymmetricConfig ();
config . setPublicKey ( "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArQfyGCvBOdgmDGU6ciGPVNB6jHsMip0b0qOrPvVTSJ/x0offjKARogA2tjGjyr3rUtwg9woMBqv/iyENR0GBnIUa0jkYsznCKeygcflnNa4mrVf7XKXLhSwtY+kCe3diPk+0QPfEsfF9/aK6pWBUFcrE8P2k2sF/8mo8dFJU1t6zQGPspHkNAgR6MLU8SjPZxnMS6EG722MdYhvSYAKsnu02Hozqb4jh/gaQ/E6NkvM3DkqIyIYsRH2smstIFEb9CCiTdiz/OsJKQLgGy/pqIVKtai3lnUxAayEV45Z61rNTOusNJf+icGhZxjqhAeoWjMxOCVmVC2GKa9sisqBgkQIDAQAB" );
StringEncryptor encryptor = new SimpleAsymmetricStringEncryptor ( config );
String message = "chupacabras" ;
String encrypted = encryptor . encrypt ( message );
System . out . printf ( "Encrypted message %s n " , encrypted );
}
}
import com . ulisesbocchio . jasyptspringboot . encryptor . SimpleAsymmetricConfig ;
import com . ulisesbocchio . jasyptspringboot . encryptor . SimpleAsymmetricStringEncryptor ;
import org . jasypt . encryption . StringEncryptor ;
import static com . ulisesbocchio . jasyptspringboot . util . AsymmetricCryptography . KeyFormat . PEM ;
public class PropertyEncryptor {
public static void main ( String [] args ) {
SimpleAsymmetricConfig config = new SimpleAsymmetricConfig ();
config . setKeyFormat ( PEM );
config . setPublicKey ( "-----BEGIN PUBLIC KEY----- n " +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArQfyGCvBOdgmDGU6ciGP n " +
"VNB6jHsMip0b0qOrPvVTSJ/x0offjKARogA2tjGjyr3rUtwg9woMBqv/iyENR0GB n " +
"nIUa0jkYsznCKeygcflnNa4mrVf7XKXLhSwtY+kCe3diPk+0QPfEsfF9/aK6pWBU n " +
"FcrE8P2k2sF/8mo8dFJU1t6zQGPspHkNAgR6MLU8SjPZxnMS6EG722MdYhvSYAKs n " +
"nu02Hozqb4jh/gaQ/E6NkvM3DkqIyIYsRH2smstIFEb9CCiTdiz/OsJKQLgGy/pq n " +
"IVKtai3lnUxAayEV45Z61rNTOusNJf+icGhZxjqhAeoWjMxOCVmVC2GKa9sisqBg n " +
"kQIDAQAB n " +
"-----END PUBLIC KEY----- n " );
StringEncryptor encryptor = new SimpleAsymmetricStringEncryptor ( config );
String message = "chupacabras" ;
String encrypted = encryptor . encrypt ( message );
System . out . printf ( "Encrypted message %s n " , encrypted );
}
}
从版本 3.0.5 开始,支持 AES 256-GCM 加密。要使用这种类型的加密,请设置属性jasypt.encryptor.gcm-secret-key-string
、 jasypt.encryptor.gcm-secret-key-location
或jasypt.encryptor.gcm-secret-key-password
。
使用的底层算法是AES/GCM/NoPadding
因此请确保已将其安装在您的 JDK 中。
SimpleGCMByteEncryptor
使用IVGenerator
来加密属性。如果您不想使用默认实现RandomIvGenerator
可以使用属性jasypt.encryptor.iv-generator-classname
进行配置
通过jasypt.encryptor.gcm-secret-key-string
或jasypt.encryptor.gcm-secret-key-location
使用密钥时,请确保以 base64 形式对密钥进行编码。 Base64 字符串值可以设置为jasypt.encryptor.gcm-secret-key-string
,或者只是将其保存在文件中并在属性jasypt.encryptor.gcm-secret-key-location
中使用 spring 资源定位器到该文件。例如:
jasypt.encryptor.gcm-secret-key-string = " PNG5egJcwiBrd+E8go1tb9PdPvuRSmLSV3jjXBmWlIU= "
# OR
jasypt.encryptor.gcm-secret-key-location =classpath:secret_key.b64
# OR
jasypt.encryptor.gcm-secret-key-location =file:/full/path/secret_key.b64
# OR
jasypt.encryptor.gcm-secret-key-location =file:relative/path/secret_key.b64
或者,您可以创建自己的StringEncryptor
bean:
@ Bean ( "encryptorBean" )
public StringEncryptor stringEncryptor () {
SimpleGCMConfig config = new SimpleGCMConfig ();
config . setSecretKey ( "PNG5egJcwiBrd+E8go1tb9PdPvuRSmLSV3jjXBmWlIU=" );
return new SimpleGCMStringEncryptor ( config );
}
或者,您可以使用密码通过 AES 256-GCM 加密/解密属性。密码用于在启动时生成密钥,因此您需要/可以设置一些属性,这些是:
jasypt.encryptor.gcm-secret-key-password = " chupacabras "
# Optional, defaults to "1000"
jasypt.encryptor.key-obtention-iterations = " 1000 "
# Optional, defaults to 0, no salt. If provided, specify the salt string in ba64 format
jasypt.encryptor.gcm-secret-key-salt = " HrqoFr44GtkAhhYN+jP8Ag== "
# Optional, defaults to PBKDF2WithHmacSHA256
jasypt.encryptor.gcm-secret-key-algorithm = " PBKDF2WithHmacSHA256 "
如果您使用外部工具加密您的机密,请确保此参数相同。或者,您可以创建自己的StringEncryptor
bean:
@ Bean ( "encryptorBean" )
public StringEncryptor stringEncryptor () {
SimpleGCMConfig config = new SimpleGCMConfig ();
config . setSecretKeyPassword ( "chupacabras" );
config . setSecretKeyIterations ( 1000 );
config . setSecretKeySalt ( "HrqoFr44GtkAhhYN+jP8Ag==" );
config . setSecretKeyAlgorithm ( "PBKDF2WithHmacSHA256" );
return new SimpleGCMStringEncryptor ( config );
}
您可以使用 Maven 插件或遵循非对称加密的加密属性中所述的类似策略
jasypt-spring-boot-demo-samples 存储库包含有效的 Spring Boot 应用程序示例。主 jasypt-spring-boot-demo 演示应用程序在应用程序运行之前使用加密密码显式设置系统属性。要获得更真实的场景,请尝试删除设置系统属性的行,使用 Maven 构建应用程序,然后运行:
java -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar --jasypt.encryptor.password=password
您将把加密密码作为命令行参数传递。像这样运行它:
java -Djasypt.encryptor.password=password -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar
您将把加密密码作为系统属性传递。
如果您需要将此属性作为环境变量传递,您可以通过创建 application.properties 或 application.yml 并添加以下内容来完成此操作:
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
或在 YAML 中
jasypt:
encryptor:
password: ${JASYPT_ENCRYPTOR_PASSWORD:}
基本上,它的作用是定义指向不同属性JASYPT_ENCRYPTOR_PASSWORD
jasypt.encryptor.password
属性,您可以使用环境变量设置该属性,也可以通过系统属性覆盖。此技术还可用于翻译您需要的任何其他库的属性名称/值。演示应用程序中也提供了此功能。所以你可以像这样运行演示应用程序:
JASYPT_ENCRYPTOR_PASSWORD=password java -jar target/jasypt-spring-boot-demo-1.5-SNAPSHOT.jar
注意:当使用 Gradle 作为构建工具时,processResources 任务会因“$”字符而失败,要解决此问题,您只需像“$”一样对该变量进行转义。
虽然 jasypt-spring-boot-demo 是一个全面的演示,展示了加密/解密属性的所有可能方法,但还有其他多个演示单独的场景。