application.yml にデータベースのパスワードを平文で書いたまま git push してしまった、という経験はないでしょうか。Gitのhistoryには機密情報がずっと残り続けます。かといってHashiCorp VaultやAWS Secrets Managerはちょっと大げさ、という場面で頼りになるのが Jasypt です。

Jasyptを使えば、既存の application.yml の構造をほぼ変えずに、パスワードなどの機密値を ENC(...) 形式の暗号化文字列に置き換えられます。Gitにコミットしても安全で、Springが起動時に自動で復号してくれます。

なぜ平文パスワードが問題なのか

spring.datasource.password: mysecretpassword のような記述をGitリポジトリにコミットすると、以下のリスクが生まれます。

  • チームメンバー全員がパスワードを閲覧できる
  • GitHubでうっかりpublicにしてしまったとき、すぐにクローラーに拾われる
  • ログ出力やエラーメッセージ経由で漏れることがある

Jasyptの仕組みをざっくり理解する

jasypt-spring-boot-starter を追加すると、Springのプロパティ読み込み処理にフックが挿入されます。ENC(...) で囲まれた値を検出したら、指定された暗号化キーで自動的に復号して、アプリケーションには平文で渡してくれます。対称鍵方式なので、このキー(jasypt.encryptor.password)をどう管理するかが責任の中心になります。

依存関係を追加する

pom.xmljasypt-spring-boot-starter と、文字列の暗号化に使うMavenプラグインを追加します。

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

<build>
  <plugins>
    <plugin>
      <groupId>com.github.ulisesbocchio</groupId>
      <artifactId>jasypt-maven-plugin</artifactId>
      <version>3.0.5</version>
    </plugin>
  </plugins>
</build>

本記事は Spring Boot 3.x(Java 17以上) を前提としています。Spring Boot 3.x 環境では追加のJCE設定は不要です。最新バージョンは Maven Central で確認してください。

Mavenプラグインで暗号化する

# 暗号化
mvn jasypt:encrypt-value \
  -Djasypt.encryptor.password="mySecretKey" \
  -Djasypt.plugin.value="mysecretpassword"

実行すると暗号化された文字列が出力されます。プラグインのバージョンによっては ENC(...) を含む形式で出力されますが、含まない場合は手動で ENC() で囲んで application.yml に貼り付けてください。

復号確認は ENC()内側の文字列だけ を渡します。

# 復号確認(ENC() の内側の文字列のみ渡す)
mvn jasypt:decrypt-value \
  -Djasypt.encryptor.password="mySecretKey" \
  -Djasypt.plugin.value="xxxxxxxx..."

ENC() ラッパーごと渡してしまうと復号が失敗します。ENC(xxxxxx) の括弧内の文字列のみを -Djasypt.plugin.value に渡してください。

application.ymlに暗号化値を埋め込む

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydb
    username: dbuser
    password: ENC(AbCdEfGhIjKlMnOpQrStUvWxYz==)

app:
  api-key: ENC(XyZ123AbC456DefGhI789==)
  jwt-secret: ENC(PqRsTuVwXyZaBcDeFgHiJkL==)

ENC() のフォーマットを間違えると起動時に例外が発生するので、コピー時に余分なスペースが入っていないか確認してください。

暗号化キーの設定方法

暗号化キーを application.yml に直書きしてはいけません。 キーをGitにコミットしてしまったら暗号化の意味がなくなります。

Spring Bootは JASYPT_ENCRYPTOR_PASSWORD のような環境変数を jasypt.encryptor.password プロパティに自動変換します(大文字・アンダースコア → 小文字・ドット)。そのため、環境変数を設定してからアプリを起動するだけでOKです。

# 環境変数を設定してアプリを起動
export JASYPT_ENCRYPTOR_PASSWORD=mySecretKey
./mvnw spring-boot:run

# java -jar で起動する場合
JASYPT_ENCRYPTOR_PASSWORD=mySecretKey java -jar target/myapp.jar

Dockerで起動する場合は -e JASYPT_ENCRYPTOR_PASSWORD=xxx をオプションに追加します。

ローカル開発時は.envファイルで管理する

チーム開発では、各開発者が .env ファイルでキーを管理するパターンが便利です。

# .env
JASYPT_ENCRYPTOR_PASSWORD=myLocalDevKey
# .gitignore に追加
.env

Spring Bootや Mavenは .env を自動では読み込まないため、direnv または dotenv-cli などのツールを使ってシェルに環境変数をロードする必要があります。

direnvを使う場合は .envrcdotenv と記述して direnv allow を実行します。dotenv-cliの場合は以下のように起動できます。

dotenv run -- ./mvnw spring-boot:run

チームには .env.example を共有して、どの変数が必要かを文書化しておくといいですね。プロファイルを使ってdev/prodで設定を切り替えるパターンと組み合わせると、環境ごとの管理がより整理できます。詳しくは Spring Bootのプロファイルで環境ごとの設定を安全に切り替える を参照してください。

設定ファイルの管理方法全般については Spring Bootの設定ファイル完全解説 も参考にしてください。

GitHub ActionsでCI/CDに組み込む

リポジトリの Settings > Secrets and variables > ActionsJASYPT_ENCRYPTOR_PASSWORD を登録して、ワークフローから参照します。

name: CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      JASYPT_ENCRYPTOR_PASSWORD: ${{ secrets.JASYPT_ENCRYPTOR_PASSWORD }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'
      - run: mvn test

アルゴリズムを強固な設定にする

jasypt-spring-boot-starter 3.x ではデフォルトのアルゴリズムはすでに PBEWITHHMACSHA512ANDAES_256 です。新規導入であれば追加設定なしで安全なアルゴリズムが使われます。

ただし明示的に記述しておくと設定の意図が伝わりやすいです。v2.x からの移行時はこの変更が必須 です(v2.xのデフォルト PBEWithMD5AndDES はMD5の衝突耐性の低さとDESの56ビット鍵長から現代では推奨されません)。

jasypt:
  encryptor:
    algorithm: PBEWITHHMACSHA512ANDAES_256
    iv-generator-classname: org.jasypt.iv.RandomIvGenerator

アルゴリズムを変更する場合は、Mavenプラグイン側にも同じアルゴリズムを指定してください(例: -Djasypt.encryptor.algorithm=PBEWITHHMACSHA512ANDAES_256)。暗号化時と復号時でアルゴリズムが食い違うと起動時にエラーになります。また既存の暗号化値はすべて再生成が必要です。

Jasyptの限界と次のステップ

Jasyptは手軽ですが、できないこともあります。

  • 鍵のローテーション がしにくい(全暗号化値の再生成が必要)
  • 監査ログ細粒度アクセス制御 はない
  • チームが大きくなるとキーの共有・管理が煩雑になる

「始めやすいが、育てにくい」というのが正直なトレードオフです。コンプライアンス要件が厳しくなってきたり、マイクロサービスが増えてきたりしたタイミングで、HashiCorp VaultやAWS Secrets Managerへの移行を検討しましょう。

application.ymlENC() 置換が完了したら、以下の3点を確認しておきましょう。

  1. .env.gitignore に追加されており、Gitに追跡されていないこと
  2. git log で機密情報の平文がhistoryに残っていないこと
  3. CI/CDパイプラインで JASYPT_ENCRYPTOR_PASSWORD が正しく注入され、テストが通ること