0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

IBMが寄贈したCBOMツールセットを使ってJavaからCBOMを生成してみる

Last updated at Posted at 2025-12-08

この記事はAIによって生成されたコンテンツを含みます。(スクショ、コマンド出力、ログ、トレースなどには含みません)

はじめに

現代のソフトウェア開発において、暗号技術は信頼性と安全性を支える基盤です。しかし、暗号アルゴリズムや鍵管理の不備は重大なセキュリティー・リスクを引き起こし、量子コンピューターの進展によりその脅威はさらに高まっています。このような背景から、暗号資産の可視化と標準化は急務となっています。

Cryptographic Bill of Materials (CBOM) は、ソフトウェアに含まれる暗号アルゴリズム、鍵、証明書、プロトコルなどを体系的に記録する仕組みであり、Linux Foundationの Post-Quantum Cryptography Alliance (PQCA) によって標準化が進められています。この取り組みを加速するため、IBMは CBOM関連ツール群をLinux Foundationに寄贈しました。その一翼を担うのが Sonar-cryptographyプラグインで、JavaやPythonのソースコードを解析し、暗号資産をCBOM形式で出力します。

本記事では、SonarQubeとSonar-cryptographyプラグインを用いてJavaコードから暗号資産を検出し、CBOMを生成する方法を紹介します。

トップに戻る

Sonar-cryptographyプラグインのセットアップ

Sonar-cryptographyの利用には SonarQubeサーバーのセットアップが必要です。SonarQubeは無料で利用できますが、エディションによって機能が異なります。

今回利用する Community Edition は、Java、JavaScript、Pythonなど主要言語の静的解析が可能で、基本的なコード品質チェック機能を提供しています。個人や小規模チームでの利用には十分な機能があり、SonarQubeの公式サイトからダウンロードしてインストールできます。

Sonar-cryptographyプラグイン (執筆時v1.4.8) をSonarQubeで使用するための要件は、SonarQube 9.9 (LTS) 以降です。

SonarQube Community Edition は Dockerでも使用可能であり、公式イメージを使用すれば、インストール作業を省略してすぐに使い始めることができます。

トップに戻る

Docker composeでSonarQubeを起動する

本番環境では PostgreSQL などの外部データベースの使用が推奨されていますが、評価・テスト目的であれば、embedded H2 database を使って起動することができます。

以下は、embedded H2 database を使った最小構成の docker-compose.yml の例です。

version: '3'

services:
  sonarqube:
    image: sonarqube:community
    container_name: sonarqube
    ports:
      - "9000:9000"
    environment:
      - SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true
    volumes:
      - ./sonarqube_data:/opt/sonarqube/data
      - ./sonarqube_extensions:/opt/sonarqube/extensions
      - ./sonarqube_logs:/opt/sonarqube/logs

任意のフォルダーを作成し、上記のdocker-compose.ymlを配置します。
永続化したいデータのために、sonarqube_datasonarqube_extensionssonarqube_logsフォルダーを作成し、docker compose up -dコマンドで起動します。

ブラウザーで http://<your-sonarqube-host>:9000 にアクセスすると、ログイン画面が表示されますので、初期ログイン情報 (admin/admin) を使ってログインし、パスワードを変更してください。

トップに戻る

Sonar-cryptographyプラグインの入手と組み込み

Sonar-cryptographyプラグインのjarファイルは、https://github.com/PQCA/sonar-cryptography/releases にアクセスして最新のリリース (執筆時は 1.4.8) を選択し、「Assets」セクションにあるcom.ibm.sonar-cryptography-plugin-<version>.jarを選択するとダウンロードできます。

少々わかりにくいですのでスクショを貼っておきますが、右側の「Assets」の下に並んでいるハイパーリンクをクリックすると、ダウンロードが始まります。

image001.jpg

Sonar-cryptographyプラグインをSonarQubeで使用するためには、コンテナー内の /opt/sonarqube/extensions/plugins/ に jarファイルを配置して、SonarQube を再起動します。
前述のdocker-compose.ymlの場合、コンテナー内のパスはホスト側のsonarqube_extensionsにマッピングされていますので、さらにpluginsフォルダーを作成して、その中に jarファイルを置きます。

プラグインが正しく読み込まれたかどうかは、SonarQubeのUIから確認できます。

  1. http://<your-sonarqube-host>:9000 にアクセスし、管理者アカウントでログインします。

  2. 上部のタブから「Administration」→「Marketplace」→「Plugins」の順に遷移します。

  3. 「Installed」を選択したリストに、「Sonar Crypto Plugin」が含まれていることを確認してください。

    image002.jpg

ここまでのインストール作業で、docker-compose.ymlを配置したフォルダーは以下のような構造になっています。(抜粋)

.:
合計 16
-rw-r--r-- 1 khirazo khirazo  353 12月  2 14:40 docker-compose.yml
drwxr-xr-x 4 khirazo khirazo 4096 12月  2 14:42 sonarqube_data
drwxr-xr-x 4 khirazo khirazo 4096 12月  2 14:42 sonarqube_extensions
drwxr-xr-x 2 khirazo khirazo 4096 12月  8 10:46 sonarqube_logs

./sonarqube_extensions:
合計 8
drwxr-xr-x 2 khirazo root    4096 12月  2 14:42 downloads
drwxr-xr-x 2 khirazo khirazo 4096 12月  2 14:30 plugins

./sonarqube_extensions/plugins:
合計 33124
-rw-r--r-- 1 khirazo khirazo 33916166 12月  2 14:23 sonar-cryptography-plugin-1.4.8.jar

トップに戻る

SonarQubeでルールを有効化する

プラグインは、SonarQubeに認識されただけではスキャンに使用されません。SonarQubeでルールを有効化するには、「Quality Profile」を編集します。

  1. SonarQube UIに管理者権限でログインし、「Quality Profiles」タブを選択します。

  2. 今回はJavaコードですので、「Java」のプロファイルを選択します。

  3. デフォルトの「Sonar way」では「Activate More」がグレーアウトされていてルールを追加できないので、カスタムプロファイルを作成します。
    「Sonar way」を開いて「⋮」メニューから「Extend」を選択すると、任意のプロファイルを作成できます。
    以下の例では、「CBOM Generation」という名前のプロファイルを作成済みです。

    image003.jpg

  4. 作成したカスタムプロファイルの右下にある「Activate More」をクリックし、「Cryptographic Inventory (CBOM)」を探してクリックします。(Java用とPython用があります)
    開いた画面に「Activate」ボタンがありますので、クリックして紐づけます。

    image004.jpg

後述しますが、スキャンする前に、このプロファイルをプロジェクトに関連付ける必要があります。

トップに戻る

Javaソースコードのスキャン

SonarQubeでJavaのソースコードをスキャンするには、以下の手順を実施します。

  1. プロジェクトを作成し、トークンを生成します。

  2. 公式ページからダウンロードしたSonarScannerをインストールし、環境変数 PATH に追加します。
    ガイド等ではMavenやGradleがよく出てきますが、今回はSonarScanner CLIを使用します。

  3. Javaプロジェクトのルートに sonar-project.properties を作成します。

  4. Javaの場合、コンパイル後にスキャンする必要がありますので、ビルドしていない場合はビルドします。
    SonarScanner CLIを使えば、MavenやGradleなしでもJavaコードをスキャンできます。

  5. スキャンの結果を確認します。
    一般的にはSonarQube UIでプロジェクトを開いて確認すると思いますが、今回の目的であるSonar-cryptographyプラグインは、Javaプロジェクトのフォルダーにcbom.jsonというファイルを出力します。

実は、SonarScanner CLIについても、インストールせずにDockerで実行できます。
そこで、今回はDockerから呼び出す形でスキャンを行いたいと思います。

トップに戻る

プロジェクトの作成とセットアップ

SonarQubeプロジェクトの作成と関連作業

SonarQubeのプロジェクトは、「Projects」タブの「Create Project」から作成します。今回はLocal projectで、名前は「My Java Project」にしました。

スキャン対象のJavaソースコードが手もとにない場合は、任意のオープンソースプロジェクト(チャットアプリなど暗号機能を持つもの)を利用するとよいでしょう。

プロジェクトを作成すると、トークンを生成できるようになります。画面の下部にある「How do you want to analyze your repository?」部分で「Locally」を選択し、「Provide a token」部分で「Generate」をクリックします。生成されたトークンはどこかにメモしておいてください。

また、先ほど作成したカスタムプロファイルを、このプロジェクトに紐づけておきます。

「Projects」タブで対象のプロジェクトを選択し、「Project Settings」→「Quality Profiles」を選びます。「Add a language」画面でJavaを選択し、プロファイルとして先ほど作成した「CBOM Generation」を選択します。

image006.jpg

トップに戻る

sonar-project.propertiesの作成

スキャン対象のJavaソースコードが置かれているフォルダーのルートに sonar-project.properties を作成し、作成したプロジェクトの情報を記述します。

今回は以下の定義を使用します。(トークンには正しい値を指定します)

sonar.projectKey=my-java-project
sonar.projectName=My Java Project
sonar.projectVersion=1.0
sonar.sources=src
sonar.java.binaries=build
sonar.host.url=http://localhost:9000
sonar.token=<your_token>

この例の場合、srcにソースコードが、buildにビルド後の classファイルが置かれています。

トップに戻る

スキャンの実施

これで準備が整いましたので、スキャンを行ってみたいと思います。

コマンドプロンプト (今回はWSL環境)を開いて、カレントフォルダーを対象のJavaプロジェクトに設定し、SonarScanner CLIをDocker経由で呼び出します。

docker run --rm \
  -e SONAR_HOST_URL="http://host.docker.internal:9000" \
  -e SONAR_LOGIN="<your_token>" \
  -v $(pwd):/usr/src \
  sonarsource/sonar-scanner-cli

この記事の検証環境は、サーバーが同じマシンのdocker compose で起動していたので、 クライアント側を docker run で起動した場合に、localhost宛では接続できませんでした。host.docker.internal を指定することで接続できましたが、OS環境によってはネットワークの定義を工夫する必要があるかもしれません。

以下は、スキャン時にコマンドラインに表示されたログの抜粋です。

06:58:02.827 INFO  Scanner configuration file: /opt/sonar-scanner/conf/sonar-scanner.properties
06:58:02.835 INFO  Project . configuration file: /usr/src/sonar-project.properties
06:58:02.880 INFO  SonarScanner CLI 7.3.0.5189
06:58:02.882 INFO  Linux 6.6.87.2-microsoft-standard-WSL2 amd64
06:58:04.427 INFO  Communicating with SonarQube Community Build 25.10.0.114319
06:58:04.428 INFO  JRE provisioning: os[linux], arch[x86_64]
06:58:06.691 INFO  Starting SonarScanner Engine...
06:58:06.691 INFO  Java 17.0.13 Eclipse Adoptium (64-bit)
06:58:05.704 INFO  Load global settings
06:58:05.793 INFO  Load global settings (done) | time=90ms
06:58:05.796 INFO  Server id: 147B411E-AZrdlS-8U3JK0eKGSgJ_
06:58:05.825 INFO  Loading required plugins
06:58:05.826 INFO  Load plugins index
06:58:05.847 INFO  Load plugins index (done) | time=21ms
06:58:05.847 INFO  Load/download plugins
06:58:06.354 INFO  Load/download plugins (done) | time=507ms
06:58:06.734 INFO  Process project properties
06:58:06.750 INFO  Process project properties (done) | time=16ms
06:58:06.785 INFO  Project key: my-java-project
06:58:06.786 INFO  Base dir: /usr/src
06:58:06.787 INFO  Working dir: /tmp/.scannerwork
06:58:06.804 INFO  Load project settings for component key: 'my-java-project'
06:58:06.826 INFO  Load project settings for component key: 'my-java-project' (done) | time=23ms
06:58:06.858 INFO  Load quality profiles
06:58:06.942 INFO  Load quality profiles (done) | time=84ms
06:58:07.015 INFO  Load active rules
06:58:07.463 INFO  Load active rules (done) | time=447ms
06:58:07.475 INFO  Load analysis cache
06:58:07.526 INFO  Load analysis cache (794 bytes) | time=51ms
06:58:07.633 INFO  Preprocessing files...
06:58:09.128 INFO  1 language detected in 18 preprocessed files (done) | time=1494ms
06:58:09.129 INFO  0 files ignored because of scm ignore settings
06:58:09.130 INFO  Loading plugins for detected languages
06:58:09.131 INFO  Load/download plugins
06:58:09.709 INFO  Load/download plugins (done) | time=578ms
06:58:09.775 INFO  Sonar Cryptography initialized in context (SONARQUBE)
06:58:09.844 INFO  Load project repositories
06:58:09.943 INFO  Load project repositories (done) | time=99ms
06:58:09.961 INFO  Indexing files...
06:58:09.962 INFO  Project configuration:
06:58:10.068 INFO  18 files indexed (done) | time=107ms
06:58:10.070 INFO  Quality profile for java: CBOM Generation
06:58:10.072 INFO  ------------- Run sensors on module My Java Project
06:58:10.096 INFO  Sonar Cryptography initialized in context (SONARQUBE)
06:58:10.140 INFO  Load metrics repository
06:58:10.162 INFO  Load metrics repository (done) | time=21ms
06:58:12.180 INFO  Sensor JavaSensor [java]
06:58:12.211 INFO  Server-side caching is enabled. The Java analyzer will not try to leverage data from a previous analysis.
06:58:12.213 INFO  Using ECJ batch to parse 15 Main java source files with batch size 204 KB.
06:58:13.069 INFO  Starting batch processing.
06:58:13.672 INFO  The Java analyzer cannot skip unchanged files in this context. A full analysis is performed for all files.
06:58:15.308 INFO  Detected (BlockCipher) AES128-ECB-PKCS5
06:58:17.765 INFO  Detected (Key) RSA
06:58:17.920 INFO  Detected (Signature) MD5withRSA
06:58:17.981 INFO  Detected (PublicKeyEncryption) RSA-2048
06:58:18.658 INFO  Detected (Key) RSA
06:58:18.686 INFO  Detected (SecretKey) AES
06:58:18.727 INFO  Detected (SecretKey) DES
06:58:18.841 INFO  Detected (Signature) MD5withRSA
06:58:18.915 INFO  Detected (PublicKeyEncryption) RSA-2048
06:58:18.926 INFO  Detected (SecretKey) AES
06:58:19.004 INFO  Detected (PublicKeyEncryption) RSA-2048
06:58:19.043 INFO  Detected (Signature) MD5withRSA
06:58:19.080 INFO  100% analyzed
06:58:19.081 INFO  Batch processing: Done.
(中略)
06:58:21.391 INFO  Executing post-job 'Output generation'
06:58:21.676 INFO  CBOM was successfully generated '/usr/src/cbom.json'.
06:58:21.678 INFO  ========== CBOM Statistics ==========
06:58:21.678 INFO  Detected Assets                  : 12
06:58:21.679 INFO   - Key                           : 2
06:58:21.679 INFO   - BlockCipher                   : 1
06:58:21.679 INFO   - SecretKey                     : 3
06:58:21.680 INFO   - Signature                     : 3
06:58:21.680 INFO   - PublicKeyEncryption           : 3
06:58:21.680 INFO  =====================================
06:58:21.691 INFO  Analysis total time: 15.251 s
06:58:21.691 INFO  SonarScanner Engine completed successfully
06:58:21.931 INFO  EXECUTION SUCCESS
06:58:21.933 INFO  Total time: 19.113s

トップに戻る

生成されたCBOMの確認

以下に、生成されたCBOMの例を示します。一部の値はダミーに置き換えています。

{
  "bomFormat" : "CycloneDX",
  "specVersion" : "1.6",
  "serialNumber" : "urn:uuid:21f02bce-eff3-41bf-a127-11e18f985f0a",
  "version" : 1,
  "metadata" : {
    "timestamp" : "2025-12-02T06:58:21Z",
    "tools" : {
      "components" : [ ],
      "services" : [
        {
          "provider" : {
            "name" : "IBM"
          },
          "name" : "Sonar Cryptography Plugin",
          "version" : "1.4.8"
        }
      ]
    }
  },
  "components" : [
    {
      "type" : "cryptographic-asset",
      "bom-ref" : "8827fa02-9a1e-4574-b648-8af5c51b43d1",
      "name" : "AES128-ECB-PKCS5",
      "evidence" : {
        "occurrences" : [
          {
            "location" : "src/Client/Encryption/AES.java",
            "line" : 118,
            "offset" : 24,
            "additionalContext" : "javax.crypto.Cipher#getInstance(Ljava/lang/String;)Ljavax/crypto/Cipher;"
          }
        ]
      },
      "cryptoProperties" : {
        "assetType" : "algorithm",
        "algorithmProperties" : {
          "primitive" : "block-cipher",
          "parameterSetIdentifier" : "128",
          "mode" : "ecb",
          "padding" : "pkcs5",
          "cryptoFunctions" : [
            "encrypt"
          ]
        },
        "oid" : "2.16.840.1.101.3.4.1"
      }
    },
    {
      "type" : "cryptographic-asset",
      "bom-ref" : "7a35f622-ff18-41cf-83f7-20e0fd100c74",
      "name" : "MD5withRSA",
      "evidence" : {
        "occurrences" : [
          {
            "location" : "src/Decrypt.java",
            "line" : 115,
            "offset" : 19,
            "additionalContext" : "java.security.Signature#getInstance(Ljava/lang/String;)Ljava/security/Signature;"
          },
          {
            "location" : "src/Client/Encryption/Decrypt.java",
            "line" : 115,
            "offset" : 19,
            "additionalContext" : "java.security.Signature#getInstance(Ljava/lang/String;)Ljava/security/Signature;"
          },
          {
            "location" : "src/Encrypt.java",
            "line" : 124,
            "offset" : 24,
            "additionalContext" : "java.security.Signature#getInstance(Ljava/lang/String;)Ljava/security/Signature;"
          }
        ]
      },
      "cryptoProperties" : {
        "assetType" : "algorithm",
        "algorithmProperties" : {
          "primitive" : "signature",
          "parameterSetIdentifier" : "2048",
          "cryptoFunctions" : [
            "verify"
          ]
        },
        "oid" : "1.2.840.113549.1.1.4"
      }
    }
  ]
}

以下に、各CBOMフィールドの簡単な説明を記します。

フィールド名 説明
bomFormat CBOMのフォーマット(例:CycloneDX)
specVersion 使用している仕様のバージョン番号
serialNumber BOMの一意な識別子(UUID形式)
version BOMのバージョン番号
metadata メタデータ全体を保持するオブジェクト
  timestamp BOMが生成された日時
  tools BOM生成に使用したツール情報
    components ソフトウェアコンポーネント情報
    services 関連するサービス情報
      provider.name BOM提供者の名前
components
  type コンポーネントの種類(例:cryptographic-asset)
  bom-ref コンポーネントの参照ID
  name 暗号資産の名前(例:AES128-ECB-PKCS5)
  evidence
    occurrences.location 該当暗号資産が検出されたソースコードの場所
    occurrences.line 該当箇所の行番号
    occurrences.offset 該当箇所のオフセット位置
    additionalContext 検出に関する追加情報(API呼び出しなど)
  cryptoProperties
    assetType 暗号資産の種類(例:algorithm、secret-key)
    algorithmProperties アルゴリズムの詳細情報(例:ブロック暗号、パラメータセット)
    parameterSetIdentifier パラメータセットの識別子(例:128、2048)
    mode 暗号モード(例:ECB、GCM)
    padding パディング方式(例:PKCS5)
    cryptoFunctions 暗号機能(例:encrypt、keygen、verify)
    oid オブジェクト識別子(OID)

CBOMは人間が直接読むことを前提としたものではなく、ツールやプロセスに組み込んで活用することが想定されています。CBOMはCycloneDX仕様に準拠した構造化データなので、専用ツールで読み込むことで、暗号資産の一覧や依存関係を可視化できます。

例えば、CBOMkitサイト上には、JSONファイルをアップロードすることで、CBOMを可視化できるサービスがあります。
ただ、CBOMは暗号情報が記されたファイルですので、見知らぬサーバーにアップロードすることは避けて、管理の行き届いた環境でcbomkitに含まれるCBOM Viewerなどを利用するほうがよいでしょう。

image007.jpg

トップに戻る

まとめ

本記事では、SonarQubeとSonar-cryptographyプラグインを用いて、Javaソースコードから暗号資産を検出し、CBOMを生成する手順を紹介しました。Docker ComposeによるSonarQube環境構築、プラグインの組み込み、ルールの有効化、そしてSonarScannerによるスキャンまでを一通り実施し、CBOMの構造と用途についても解説しました。

CBOMは人間が直接読むことを目的としたものではなく、セキュリティー評価やコンプライアンス対応、量子安全性移行計画の基盤として、ツールやプロセスに組み込んで活用することが想定されています。今回の手法をCI/CDパイプラインに統合すれば、暗号資産の棚卸しを自動化し、リスク管理を継続的に行うことができます。

現在のところSonar-cryptographyプラグインは、JavaのJCAとBouncyCastle、および Pythonのpyca/cryptographyに対応しています。もしそれで足りない場合は、商用製品も検討してみてください。例えば、IBM Quantum Safe Explorerは、執筆時点で C、C++、C#、Dart、Go、Java、Pythonに対応しており、JavaとPythonについても、Sonar-cryptographyプラグインよりも多くのライブラリーに対応しています。

また、CBOMは暗号アルゴリズムや鍵の強度をチェックしたり脆弱な設定を検出したりするものではなく、暗号の使用箇所を見つけてくれるものです。前述のCBOM Viewerのスクリーンショットにコンプライアンス・チェック結果のようなものが含まれていますが、それはあくまでもCBOMを解釈する側の機能となります。このあたりについても、商用製品では脆弱性診断を含めた機能(例えばCWE-327の検出など)を持っている場合がありますので、目的に応じてツールを使い分けるとよいでしょう。

トップに戻る

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?