ulisesbocchio / jasypt-spring-boot

Jasypt integration for Spring boot
MIT License
2.88k stars 514 forks source link

Failed to bind properties under 'spring.datasource.password' to java.lang.String` #154

Closed jbarton-ysg closed 4 years ago

jbarton-ysg commented 5 years ago

getting several errors I have tried setting this up with first option it says

"encryptable properties will be enabled across the entire Spring Environment "

I am not sure where to put the password or how it knows what the password is to decrypt it

I have the encoded input in my property file like so

spring.datasource.password=ENC(du+QBwMsZb4kXSQI/eIL1RU46vtOgYZU)

Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.datasource.password' to java.lang.String

Caused by: org.springframework.cache.Cache$ValueRetrievalException: Value for key 'spring.datasource.password' could not be loaded using 'com.ulisesbocchio.jasyptspringboot.caching.CachingDelegateEncryptablePropertySourc

Caused by: java.lang.IllegalStateException: either 'jasypt.encryptor.password' or one of ['jasypt.encryptor.privateKeyString', 'jasypt.encryptor.privateKeyLocation'] must be provided for Password-based or Asymmetric encryption

jbarton-ysg commented 5 years ago

figured it out have to set as environment variable

tried setting this in /etc/environment APP_ENCRYPTION_PASSWORD but still not working

jbarton-ysg commented 5 years ago

I still cannot figure out how to make this work

it works if I set this jasypt.encryptor.password in property file but then that defeats the purpose

jbarton-ysg commented 5 years ago

Have tried this export JAVA_OPTS="jasypt.encryptor.password=password but still does not work only works if I put it in the application.properties file

curtistee commented 5 years ago

Try adding it as an argument when running your app; e.g. -Djasypt.encryptor.password={my password} & see if that works.

On Fri, Sep 6, 2019 at 1:24 PM jbarton-ysg notifications@github.com wrote:

Have tried this export JAVA_OPTS="jasypt.encryptor.password=password but still does not work only works if I put it in the application.properties file

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ulisesbocchio/jasypt-spring-boot/issues/154?email_source=notifications&email_token=AAAWJDATM47KYT4PDPM3CHLQIK36FA5CNFSM4IULF3D2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6D6ZJI#issuecomment-529001637, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAWJDFWMFDV4ESWJMXDSZLQIK36FANCNFSM4IULF3DQ .

ulisesbocchio commented 5 years ago

@jbarton-ysg the property is named jasypt.encryptor.password, with relaxed bindings you can set an env var with name JASYPT_ENCRYPTOR_PASSWORD. If you really wanna call it APP_ENCRYPTION_PASSWORD you can set in your application.properties:

jasypt.encryptor.password=${APP_ENCRYPTION_PASSWORD}

And THEN set the ENV var APP_ENCRYPTION_PASSWORD

jbarton-ysg commented 5 years ago

I think I got it to work tomcat still having trouble starting tho

jbarton-ysg commented 5 years ago

getting errors on startup

Initializing Default Property Resolver 2019-09-09 13:40:33.406 INFO 6339 --- [ main] c.u.j.d.DefaultLazyPropertyDetector : Property Detector custom Bean not found with name 'encryptablePropertyDetector'. Initializing Default Property Detector 2019-09-09 13:40:33.576 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : String Encryptor custom Bean not found with name 'jasyptStringEncryptor'. Initializing Default String Encryptor 2019-09-09 13:40:33.590 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.algorithm, using default value: PBEWithMD5AndDES 2019-09-09 13:40:33.591 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.keyObtentionIterations, using default value: 1000 2019-09-09 13:40:33.592 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.poolSize, using default value: 1 2019-09-09 13:40:33.593 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.providerName, using default value: null 2019-09-09 13:40:33.593 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.providerClassName, using default value: null 2019-09-09 13:40:33.594 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.saltGeneratorClassname, using default value: org.jasypt.salt.RandomSaltGenerator 2019-09-09 13:40:33.597 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.ivGeneratorClassname, using default value: org.jasypt.salt.NoOpIVGenerator 2019-09-09 13:40:33.600 INFO 6339 --- [ main] c.u.j.encryptor.DefaultLazyEncryptor : Encryptor config not found for property jasypt.encryptor.stringOutputType,

jbarton-ysg commented 5 years ago

what is the best way to make this work with tomcat?

jbarton-ysg commented 5 years ago

I don't see then authentication error but am getting this after adding jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD}

and doing `export JASYPT_ENCRYPTOR_PASSWORD=local'

local is my local secret for decrypting password

09-Sep-2019 14:21:22.891 WARNING [main] org.apache.catalina.core.StandardServer.await The socket listening for the shutdown command experienced an unexpected timeout [97,515] milliseconds after the call to accept(). Is this an instance of bug 56684? java.net.SocketTimeoutException: Accept timed out I've tried restarting the vagrant box but keep getting same issue

jbarton-ysg commented 5 years ago

it only works if I have jasypt.encryptor.password=local in my property file using environment variable causes application not to load

jbarton-ysg commented 5 years ago

I think the issue is I get this when trying to use the system environment variable

Property Resolver custom Bean not found with name 'encryptablePropertyResolver'. Initializing Default Property Resolve

` Failed to bind properties under 'spring.datasource.password' to java.lang.String:

Reason: Could not resolve placeholder 'JASYPT_ENCRYPTOR_PASSWORD' in value "${JASYPT_ENCRYPTOR_PASSWORD}"

Action:`

jbarton-ysg commented 5 years ago

I don't think spring boot is reading environment variables from my property file do I need to do anything to enable this? I tried to make the password for the db an environment variable and it would not connect when trying to use it

jbarton-ysg commented 5 years ago

Try adding it as an argument when running your app; e.g. -Djasypt.encryptor.password={my password} & see if that works. On Fri, Sep 6, 2019 at 1:24 PM jbarton-ysg @.***> wrote: Have tried this export JAVA_OPTS="jasypt.encryptor.password=password but still does not work only works if I put it in the application.properties file — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#154?email_source=notifications&email_token=AAAWJDATM47KYT4PDPM3CHLQIK36FA5CNFSM4IULF3D2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6D6ZJI#issuecomment-529001637>, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAWJDFWMFDV4ESWJMXDSZLQIK36FANCNFSM4IULF3DQ .

I need to run this with tomcat

jbarton-ysg commented 5 years ago

@jbarton-ysg the property is named jasypt.encryptor.password, with relaxed bindings you can set an env var with name JASYPT_ENCRYPTOR_PASSWORD. If you really wanna call it APP_ENCRYPTION_PASSWORD you can set in your application.properties:

jasypt.encryptor.password=${APP_ENCRYPTION_PASSWORD}

And THEN set the ENV var APP_ENCRYPTION_PASSWORD

I've tried this but seems its not reading my environment variable I can echo it in the console tho

ulisesbocchio commented 4 years ago

@jbarton-ysg can you try one of the apps here: https://github.com/ulisesbocchio/jasypt-spring-boot-samples and check/compare with your code. It should be pretty straightforward. For JAVA_OPTS your passing it wrong. It should be:

export JAVA_OPTS="-Djasypt.encryptor.password=password"
atifkrblkr commented 4 years ago

@ulisesbocchio Apparently, the problem comes from EncryptionOperationNotPossibleException. There seems to be a problem when I use the default encryptor bean.

The default encryptor bean uses "PBEWithHMACSHA512AndAES_256" algorithm. From documentation, I know for PBE-AES-based algorithms, the IV generator is MANDATORY. The IV Generator for this algorithm is RandomIvGenerator. RandomIvGenerator has method includePlainIvInEncryptionResults() set to return true.

The problem occurs at line 398 - 400 of StandardPBEByteEncryptor in the decrypt method.

Debugging

RandomSaltGenerator.includePlainSaltInEncryptionResults=true
RandomIvGenerator.includePlainIvInEncryptionResults=true
this.ivSizeBytes=16
this.saltSizeBytes=16
encryptedMessage.length=24
if (this.saltGenerator.includePlainSaltInEncryptionResults() && this.ivGenerator.includePlainIvInEncryptionResults()) {
    if (encryptedMessage.length <= this.saltSizeBytes + this.ivSizeBytes) {
        throw new EncryptionOperationNotPossibleException();
    }
}

When I create an custom encryptor bean even with no custom configuration, the algorithm it defaults to is "PBEWithMD5AndDES". This uses the NoIvGenerator which return false on calling the method includePlainIvInEncryptionResults.

NoIvGenerator.includePlainSaltInEncryptionResults=false

I am using jasypt-spring-boot-starter v3.0.0.

@jbarton-ysg For now, the work around seems to be defining a custom StringEncryptor like so ->

application.properties

jasypt.encryptor.pool-size=4
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD}
jasypt.encryptor.bean=jasyptEncryptor

Spring Boot Configuration

@Configuration
public class SecurityConfig {

    @Bean
    @ConfigurationProperties("jasypt.encryptor")
    public SimpleStringPBEConfig jasypConfig() {
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        return config;
    }

    @Bean
    public StringEncryptor jasyptEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        encryptor.setConfig(jasypConfig());
        return encryptor;
    }
}

Hope this helps to fix the underlying bug.

ulisesbocchio commented 4 years ago

@atifkrblkr I'm not sure i follow. This is the custom encryptor bean from the sample project jasypt-spring-boot-demo which works just fine:

    @Bean(name = "encryptorBean")
    static public StringEncryptor stringEncryptor() {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword("password");
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.NoIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        return encryptor;
    }

And uses NoIvGenerator and as you state from your piece of code from the PBE Byte encryptor:

if (this.saltGenerator.includePlainSaltInEncryptionResults() && this.ivGenerator.includePlainIvInEncryptionResults()) {
    if (encryptedMessage.length <= this.saltSizeBytes + this.ivSizeBytes) {
        throw new EncryptionOperationNotPossibleException();
    }
}

where includePlainIvInEncryptionResults is false, which means that EncryptionOperationNotPossibleException could never be thrown.... since it will never pass the first if. That error is usually thrown when you try to decrypt a string using PBEWithHMACSHA512AndAES_256 and RandomIvGenerator but your string was actually encrypted with a different algorithm, such as PBEWithMD5AndDES. On which case the encrypted string has no length sufficient to contain salt and iv bytes for obvious reason

afrancis-incomm commented 4 years ago

I faced same issue when upgrading from 2.1.2 to 3.0.0. I guess the default algorithm has changed now. I tried what both of you suggested but my app only started when I used the beans that @atifkrblkr had defined in his comment above.

jzlima commented 4 years ago

mee too!

Gopinath2409 commented 4 years ago

I also faced the same issue. Today i tried using spring boot jasypt library for password encryption and was continuously facing the same issue. I was using version 3.0.0. I am using jasypt 1.9.3 dist. When i was going through this post to resolve my issue and when i particularly read @afrancis-incomm comment i tried changing my version from 3.0.0 to 2.1.2(downgraded) and it worked. So it seems the issue is in 3.0.0. I also gone through the jasypt-spring-boot-demo demos to find a solution given by @ulisesbocchio. The reason why this demo works may be is the version of the dependency. May be if the version points to 3.0.0 the demo may not work. Please help us with this!

ulisesbocchio commented 4 years ago

If you were using default config before 3.0.0 (Major release, breaking changes) you need to set:

jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

Since the default algorithm changed, to keep your encrypted properties. Otherwise, you have to re-encrypt your properties.

tzieleniewski commented 4 years ago

@ulisesbocchio I've encountered the same issue. What is the default algorithm now for 3.0.0+ versions?

mananvyas commented 4 years ago

@ulisesbocchio I am also facing same issue while trying to use with spring security Configuration details as follows: application.properties

spring.security.user.name=user
spring.security.user.password=ENC(BcvdJW/La/AVFGjh3Yhm9Q==)
spring.security.user.roles=USER

Dependency:

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

Error:

***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'spring.security.user.password' to java.lang.String:
Reason: Failed to bind properties under 'spring.security.user.password' to java.lang.String
Action:
Update your application's configuration

I am passing VM Option argument as follows: -Djasypt.encryptor.password=helloworld

Note: As Gopinath2409 has mentioned - If I downgrade it to version 2.0.0 It works fine. Thank you.

costalopes71 commented 3 years ago

Hey guys... I faced the same problem as you all... I managed to make it work by doing the following:

It worked fine for me. Im using: jasypt-spring-boot-starter 3.0.3 spring-boot 2.4.2

Hope that help you guys. Cheers

sneeli18 commented 3 years ago

$ sign in my password caused it to fail to run from terminal.

thinking4java commented 3 years ago

Hey guys... I faced the same problem as you all... I managed to make it work by doing the following:

  • 1st: encrypt your password using PBEWithMD5AndTripleDES algorithm, example: ./encrypt.sh input="admin123" password=<myEncryptionPassword> algorithm=PBEWithMD5AndTripleDES
  • 2st: After doing that, in your application.properties include these properties:
jasypt.encryptor.password=<yourPassword>
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndTripleDES

It worked fine for me. Im using: jasypt-spring-boot-starter 3.0.3 spring-boot 2.4.2

Hope that help you guys. Cheers

It works fine for me, thx

BasBastiaansen commented 3 years ago

Hey guys... I faced the same problem as you all... I managed to make it work by doing the following:

  • 1st: encrypt your password using PBEWithMD5AndTripleDES algorithm, example: ./encrypt.sh input="admin123" password=<myEncryptionPassword> algorithm=PBEWithMD5AndTripleDES
  • 2st: After doing that, in your application.properties include these properties:
jasypt.encryptor.password=<yourPassword>
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndTripleDES

It worked fine for me. Im using: jasypt-spring-boot-starter 3.0.3 spring-boot 2.4.2

Hope that help you guys. Cheers

This works, but the issue is that the password is now in application.properties. We don't want that for security reasons, that's why we use jasypt in the first place. Might as well not use jasypt at all then...

costalopes71 commented 3 years ago

Hey guys... I faced the same problem as you all... I managed to make it work by doing the following:

  • 1st: encrypt your password using PBEWithMD5AndTripleDES algorithm, example: ./encrypt.sh input="admin123" password=<myEncryptionPassword> algorithm=PBEWithMD5AndTripleDES
  • 2st: After doing that, in your application.properties include these properties:
jasypt.encryptor.password=<yourPassword>
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndTripleDES

It worked fine for me. Im using: jasypt-spring-boot-starter 3.0.3 spring-boot 2.4.2 Hope that help you guys. Cheers

This works, but the issue is that the password is now in application.properties. We don't want that for security reasons, that's why we use jasypt in the first place. Might as well not use jasypt at all then...

Good evening @BasBastiaansen, Yes, I added the password, algorithm and the generator in my application.properties. But I added their values loading from system enviroment variables. In my case, this was enough.

Example of my application.properties:

#SERVER CONFIGURATIONS
server.port=443
server.ssl.key-store-password=ENC(ENCRYPTED_VALUE)
server.ssl.key-store=ENC(ENCRYPTED_VALUE)
server.ssl.key-store-type=ENC(ENCRYPTED_VALUE)
server.ssl.key-alias=ENC(ENCRYPTED_VALUE)
http.port=80

#JASYPT
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
jasypt.encryptor.iv-generator-classname=${JASYPT_ENCRYPTOR_CLASSNAME:}
jasypt.encryptor.algorithm=${JASYPT_ENCRYPTOR_ALGORITHM:}

Hope I could help, Cheers

BasBastiaansen commented 3 years ago

Hey guys... I faced the same problem as you all... I managed to make it work by doing the following:

  • 1st: encrypt your password using PBEWithMD5AndTripleDES algorithm, example: ./encrypt.sh input="admin123" password=<myEncryptionPassword> algorithm=PBEWithMD5AndTripleDES
  • 2st: After doing that, in your application.properties include these properties:
jasypt.encryptor.password=<yourPassword>
jasypt.encryptor.iv-generator-classname=org.jasypt.iv.NoIvGenerator
jasypt.encryptor.algorithm=PBEWithMD5AndTripleDES

It worked fine for me. Im using: jasypt-spring-boot-starter 3.0.3 spring-boot 2.4.2 Hope that help you guys. Cheers

This works, but the issue is that the password is now in application.properties. We don't want that for security reasons, that's why we use jasypt in the first place. Might as well not use jasypt at all then...

Good evening @BasBastiaansen, Yes, I added the password, algorithm and the generator in my application.properties. But I added their values loading from system enviroment variables. In my case, this was enough.

Example of my application.properties:

#SERVER CONFIGURATIONS
server.port=443
server.ssl.key-store-password=ENC(ENCRYPTED_VALUE)
server.ssl.key-store=ENC(ENCRYPTED_VALUE)
server.ssl.key-store-type=ENC(ENCRYPTED_VALUE)
server.ssl.key-alias=ENC(ENCRYPTED_VALUE)
http.port=80

#JASYPT
jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD:}
jasypt.encryptor.iv-generator-classname=${JASYPT_ENCRYPTOR_CLASSNAME:}
jasypt.encryptor.algorithm=${JASYPT_ENCRYPTOR_ALGORITHM:}

Hope I could help, Cheers

Yes, this should do it, thanks!

sabeeshvk commented 1 year ago

This worked for me. I have set JASYPT_ENCRYPTOR_PASSWORD value in .zprofile

jasypt.encryptor.poolSize=4 jasypt.encryptor.password=${JASYPT_ENCRYPTOR_PASSWORD} jasypt.encryptor.bean=jasyptEncryptor

SecurityConfig.java as. above

And pom.xml

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

From logs

2022-11-27 18:10:59.109 INFO 13649 --- [ main] c.u.j.EncryptablePropertySourceConverter : Skipping PropertySource configurationProperties [class org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource 2022-11-27 18:10:59.109 INFO 13649 --- [ main] c.u.j.EncryptablePropertySourceConverter : Skipping PropertySource servletConfigInitParams [class org.springframework.core.env.PropertySource$StubPropertySource 2022-11-27 18:10:59.109 INFO 13649 --- [ main] c.u.j.EncryptablePropertySourceConverter : Skipping PropertySource servletContextInitParams [class org.springframework.core.env.PropertySource$StubPropertySource 2022-11-27 18:10:59.109 INFO 13649 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource systemProperties [org.springframework.core.env.PropertiesPropertySource] to EncryptableMapPropertySourceWrapper 2022-11-27 18:10:59.109 INFO 13649 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource systemEnvironment [org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource] to EncryptableSystemEnvironmentPropertySourceWrapper 2022-11-27 18:10:59.110 INFO 13649 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource random [org.springframework.boot.env.RandomValuePropertySource] to EncryptablePropertySourceWrapper 2022-11-27 18:10:59.110 INFO 13649 --- [ main] c.u.j.EncryptablePropertySourceConverter : Converting PropertySource Config resource 'class path resource [application.properties]' via location 'optional:classpath:/' [org.springframework.boot.env.OriginTrackedMapPropertySource] to EncryptableMapPropertySourceWrapper 2022-11-27 18:10:59.277 INFO 13649 --- [ main] c.u.j.filter.DefaultLazyPropertyFilter : Property Filter custom Bean not found with name 'encryptablePropertyFilter'. Initializing Default Property Filter 2022-11-27 18:10:59.281 INFO 13649 --- [ main] c.u.j.r.DefaultLazyPropertyResolver : Property Resolver custom Bean not found with name 'encryptablePropertyResolver'. Initializing Default Property Resolver