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?

Java 8環境でSSHJを使ってSFTP接続する際の「Algorithm X25519 not available」の解決

0
Posted at

はじめに(背景)

Java 8環境で最新の暗号化アルゴリズム(ed25519)SFTPサーバーに接続しようとした際、SSHJライブラリで net.schmizz.sshj.transport.TransportException: Algorithm X25519 not available というエラーに直面しました。その解決までの経過を備忘がてら投稿します。

1. 発生した問題

Java 8 (8u411) 上で SSHJ を使用し、秘密鍵認証によるSFTP接続を試みたところ、接続(connect)フェーズで以下の例外が発生しました。

```
Caused by: java.security.NoSuchAlgorithmException: Algorithm X25519 not available
    at javax.crypto.KeyAgreement.getInstance(KeyAgreement.java:184)
    at net.schmizz.sshj.common.SecurityUtils.getKeyAgreement(SecurityUtils.java:152)
```

2. 解決に向けたアプローチ

ステップ1:Bouncy Castleの導入

Java標準で足りない暗号アルゴリズムを補うため、Bouncy Castle をプロジェクトに追加します。

ちなみに、Bouncy Castle のバージョンについて 1.70 を指定しています。より新しいバージョンも存在しますが、調べたところ、Java 8 環境(特に古いアップデート版や32bit VM)での動作実績が豊富で、依存関係の競合が少ないこのバージョンを今回は採用しました。 要するにJava8で動かすのに適したバージョンがこちら、ということです。
プロジェクトの要件や最新の脆弱性情報を確認した上で、必要に応じて最新版(1.7x〜)への差し替えを検討してください。

Maven依存関係:(pom.xml)
```xml
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
```

ステップ2:セキュリティプロバイダの優先順位設定

単にライブラリを入れるだけでなく、Javaのセキュリティプロバイダの先頭に登録し、SSHJが確実にそれを使用するように設定します。

if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
    // 優先順位1位で登録
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
}

ステップ3:問題のあるアルゴリズムの除外(決定打)

Bouncy Castleを登録してもなお、名前の解決順位や環境依存によりエラーが消えない場合があります。その場合、「Java 8で不安定な X25519 を使用リストから外す」 設定が最も確実です。

DefaultConfig が返すリストは固定長(Unmodifiable)であるため、一度 ArrayList にコピーしてから操作するのがポイントです。

ちなみに、このポイントで私はかなり沼りました。。

// 修正不可能なリストをコピーしてそれを設定し、上書きする形で編集する
List<Factory.Named<KeyExchange>> kexFactories = new ArrayList<>(config.getKeyExchangeFactories());
// Java 8でエラーの原因となるCurve25519を除外
kexFactories.removeIf(f -> f.getName().contains("curve25519"));
config.setKeyExchangeFactories(kexFactories);

3. 最終的なコード(Java 8対応版)

import net.schmizz.sshj.DefaultConfig;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.Factory;
import net.schmizz.sshj.transport.kex.KeyExchange;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.security.Security;
import java.util.ArrayList;
import java.util.List;

public class SftpSafeDownloader {
    public void download() throws Exception {
        // 1. Bouncy Castleの登録
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.insertProviderAt(new BouncyCastleProvider(), 1);
        }

        // 2. 設定のカスタマイズ
        DefaultConfig config = new DefaultConfig();
        
        // 修正不可能なリストをコピーして編集可能にする
        List<Factory.Named<KeyExchange>> kexFactories = new ArrayList<>(config.getKeyExchangeFactories());
        // Java 8でエラーの原因となるCurve25519を除外
        kexFactories.removeIf(f -> f.getName().contains("curve25519"));
        config.setKeyExchangeFactories(kexFactories);

        // 3. 接続実行
        try (SSHClient ssh = new SSHClient(config)) {
            // 注意: PromiscuousVerifierはホストキー検証をスキップするため、本番環境での使用は推奨されません。
            // 実際の運用では、KnownHostsManagerなどを用いて適切にホストキーを検証してください。
            ssh.addHostKeyVerifier(new PromiscuousVerifier());
            ssh.connect("hostname");
            
            // 秘密鍵による認証
            ssh.authPublickey("user", ssh.loadKeys("path/to/private_key.pem"));

            try (SFTPClient sftp = ssh.newSFTPClient()) {
                sftp.get("remote_path", new FileSystemFile("local_path"));
            }
        }
    }
}

※補足
PromiscuousVerifier(直訳すると「無差別な検証者」)は、接続先のサーバーが本物かどうかを確認せず、全てのホストキーを無条件で受け入れる設定です。

まとめ

  • Java 8で最新のSSHアルゴリズムを扱うには Bouncy Castle が必須。
  • Algorithm X25519 not available が出た場合、中途半端に対応するより、使用アルゴリズムから除外して安定したアルゴリズム(NIST P-256等)にフォールバックさせるのが有効です。レガシー環境での運用においてはこちらを検討ください。
  • DefaultConfig のリスト操作時は UnsupportedOperationException に注意(コピーしてから操作する)。
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?