feat: decrypt Jasypt values in .env and Spring files
CI / Checks (pull_request) Successful in 39s
PR title / Conventional title (pull_request) Successful in 1s

ENC(...) values are decrypted on reveal, copy or get with
jasypt-spring-boot's default algorithm (3.0+, PBEWITHHMACSHA512ANDAES_256).

- The password is, as in Spring, $JASYPT_ENCRYPTOR_PASSWORD, else the
  file's own jasypt.encryptor.password (JASYPT_ENCRYPTOR_PASSWORD in a
  .env), with ${VAR} and ${VAR:default} read from the environment.
- Errors say which password was used, or which one is missing.
- Secrets show a detail after their name: jasypt, or reference for a
  Spring ${VAR}; also in Go to and Favourites.
- A .env whose values are all Jasypt isn't marked as plain text in git.
This commit is contained in:
keb committed 2026-10-15 13:31:05 +02:00
1 parent 96395cb6a2
commit e1f86c72f7
13 files changed
+381 -29

No files matched your search

+37
View File
@@ -0,0 +1,37 @@
package jasypt
import (
"errors"
"testing"
)
// Encrypted by Jasypt 1.9.3 itself, set up as jasypt-spring-boot's default
// encryptor, with the password "test-password".
var vectors = map[string]string{
"ENC(5IQUKT4B7j38TnZJ+BlWqo/zSkKHTjl4XRJyaQEHgkCy4r00avLt4dWqFB74X0Zw)": "hunter2",
"ENC(w4pm2JVZcbG5R+Ud9uKHg8VhJ/0aAK7sFXtNBv+Vo450SAchTQtfhw0TnIJ9gN+D0VFbwqJzfXU369coTJz2rw==)": "blåbærsyltetøy ✓",
}
func TestDecrypt(t *testing.T) {
for enc, want := range vectors {
if !Is(enc) {
t.Errorf("%s: not Jasypt", enc)
}
if got, err := Decrypt(enc, "test-password"); err != nil || got != want {
t.Errorf("%s: %q %v, want %q", enc, got, err, want)
}
if _, err := Decrypt(enc, "wrong"); !errors.Is(err, ErrDecrypt) {
t.Errorf("%s with a wrong password: %v", enc, err)
}
}
for _, v := range []string{"ENC(not base64!)", "ENC(aGVsbG8=)"} {
if _, err := Decrypt(v, "test-password"); err == nil {
t.Errorf("%s: no error", v)
}
}
for _, v := range []string{"ENC()", "hunter2", "ENC[AES256_GCM,data:x]", "${DB_PASSWORD}"} {
if Is(v) {
t.Errorf("%s: Jasypt", v)
}
}
}