source

JSch 사용 시 "비활성 개인 키"

factcode 2022. 9. 25. 00:14
반응형

JSch 사용 시 "비활성 개인 키"

Java 어플리케이션에서 Git으로 작업하기 위해 다음과 같은 코드를 사용하고 있습니다.유효한 키(항상 사용)를 가지고 있으며, 이 특정 코드가 이전에는 같은 키와 git 저장소에서 기능했지만, 현재는 다음과 같은 예외가 있습니다.

비활성 개인 키: [B@59c40796]

이 행에서는:

jSch.addIdentity("<key_path>/private_key.pem");

전체 코드:

    String remoteURL = "ssh://git@<git_repository>";
    TransportConfigCallback transportConfigCallback = new SshTransportConfigCallback();
    File gitFolder = new File(workingDirectory);
    if (gitFolder.exists()) FileUtils.delete(gitFolder, FileUtils.RECURSIVE);

    Git git = Git.cloneRepository()
            .setURI(remoteURL)
            .setTransportConfigCallback(transportConfigCallback)
            .setDirectory(new File(workingDirectory))
            .call();
}


private static class SshTransportConfigCallback implements TransportConfigCallback {
    private final SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
        @Override
        protected void configure(OpenSshConfig.Host hc, Session session) {
            session.setConfig("StrictHostKeyChecking", "no");
        }

        @Override
        protected JSch createDefaultJSch(FS fs) throws JSchException {
            JSch jSch = super.createDefaultJSch(fs);
            jSch.addIdentity("<key_path>/private_key.pem");

            return jSch;
        }
    };

온라인 검색 후 createDefault를 변경했습니다.pemWriter를 사용하려면 JSch:

@Override
protected JSch createDefaultJSch(FS fs) throws JSchException {
    JSch jSch = super.createDefaultJSch(fs);
    byte[] privateKeyPEM = null;

    try {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        List<String> lines = Files.readAllLines(Paths.get("<my_key>.pem"), StandardCharsets.US_ASCII);
        PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(String.join("", lines)));
        RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(privSpec);

        PKCS8Generator pkcs8 = new PKCS8Generator(privKey);

        StringWriter writer = new StringWriter();
        PemWriter pemWriter = new PemWriter(writer);
        pemWriter.writeObject(pkcs8);

        privateKeyPEM = writer.toString().getBytes("US-ASCII");

    } catch (Exception e) {
        e.printStackTrace();
    }

    jSch.addIdentity("git", privateKeyPEM, null, null);

    return jSch;
}

하지만 여전히 "비활성 개인 키" 예외가 발생합니다.

OpenSSH의 최신 버전(7.8 이후)에서는 기본적으로 다음과 같은 새로운 OpenSSH 형식의 가 생성됩니다.

-----BEGIN OPENSSH PRIVATE KEY-----

JSch는 이 키 형식을 지원하지 않습니다.


를 사용하여 키를 클래식 OpenSSH 형식으로 변환할 수 있습니다.

ssh-keygen -p -f <privateKeyFile> -m pem -P passphrase -N passphrase

을 합니다.-p(패스프레이즈 변경) 명령어. 키 .-f새로운 개인 키를 표준 OpenSSH 형식으로 사용하는 옵션(pem현재 패스프레이즈를 새 패스프레이즈로 유지할 수 있습니다.되어 있지 는, 「」를 합니다.""passphrase 다음ㄹ게요를 하시면 됩니다.ssh-keygen -y -e -f <privateKeyFile> >temp.pub공개 키를 비교하고 기존 공개 키가 새로운 형식의 개인 키와 함께 작동하는지 확인합니다.

「」: 「」해 주세요.ssh-keygen.exe는 Windows 10/11 에 내장되어 있습니다.또한 이전 버전의 Windows용 Microsoft Win32-OpenSSH 프로젝트에서 다운로드할 수 있습니다.


Windows 에서는, PuTTYgen(PuTTY 패키지에서)도 사용할 수 있습니다.

  • PuTTYgen 시작
  • 키를 로드하다
  • [ Conversions ]> [ Export Open ]으로 이동합니다.SSH
    RSA 키의 경우 기존 형식을 사용합니다.

「」를 사용해 .ssh-keygen를 추가하여 새로운 키를 클래식 형식으로 생성합니다.

ssh-keygen -m PEM

저도 우연히 이 문제를 발견했어요.Mac에서 Jgit을 실행하고 있습니다.일부 사용자에게는 다음과 같은 예외가 있습니다.

org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:160)
    at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:137)
    at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:274)
    at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:169)
    at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:136)
    at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:122)
    at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1236)
    at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:234)
    ... 17 more
Caused by: com.jcraft.jsch.JSchException: invalid privatekey: [B@e4487af
    at com.jcraft.jsch.KeyPair.load(KeyPair.java:664)
    at com.jcraft.jsch.KeyPair.load(KeyPair.java:561)
    at com.jcraft.jsch.IdentityFile.newInstance(IdentityFile.java:40)
    at com.jcraft.jsch.JSch.addIdentity(JSch.java:407)
    at com.jcraft.jsch.JSch.addIdentity(JSch.java:367)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.getJSch(JschConfigSessionFactory.java:276)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.createSession(JschConfigSessionFactory.java:220)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.createSession(JschConfigSessionFactory.java:176)
    at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:110)

근본 원인은 ssh 개인 키의 불일치임이 발견되었습니다.이 예외가 발생한 것은 새로운 종류의 ed25519 키를 가진 사용자에게만 해당됩니다.이러한 키는 다음 키헤더를 출력합니다.

-----BEGIN OPENSSH PRIVATE KEY-----

종류 RSA 대신:

-----BEGIN RSA PRIVATE KEY-----

키 (RSA 키 재생성)(ssh-keygen -t rsa을 사용하다

하다OpenSSH 7.8 생성 -m PEM 생성.ssh-keygen -t rsa -m PEM

「 」를 변환하는 에, 「」를 합니다.OPENSSH원래의 JSch가 서포트하고 있는 포맷으로의 키 포맷은, JSch의 포크로 전환할 수도 있습니다.이 포크는 https://github.com/mwiede/jsch 에서 구할 수 있습니다.

Maven 를 JSch Maven으로 .com.github.mwiede:jsch:0.1.61.

는 크음음음음 the the the the the the 를 지탱하고 있습니다.OPENSSHOpenSSH 서버는 허용되는 알고리즘 세트를 가장 안전한 알고리즘으로 제한하기 때문에 향후 중요해질 수 있습니다.

회답이 늦었지만, 이 문제에 어떻게 대처해야 할지는 남겨두고 싶습니다.

바와 같이 실제로 이며 Meny에서는 키를 할 수 있습니다.-m PEM이치노

그러나 공용 부분이 이미 여러 서버에 설치되어 있기 때문에 키를 재생성할 수 없는 경우에도 개인 키를 적절한 형식으로 변환할 수 있습니다.

그러기 위해서는 다음 명령어를 발행하기만 하면 됩니다.

ssh-keygen -p -m pem -f id_rsa

새로운 패스프레이즈를 입력하도록 요구됩니다. " " " 가 붙은 경우-P 패스프레이즈)및 ('오래된 패스프레이즈')-N(새로운 패스프레이즈) 필요한 경우 한 번에 입력할 수 있습니다.

JSch는 이 키 형식을 지원하지 않습니다.RSAPrivateKey만 지원합니다.이 명령어는 나에게 효과가 있다.이 솔루션을 사용해 보세요.

ssh-keygen -m PEM -t rsa -b 2048

//2048 키 크기에서 rsa에 추가

  1. 을 읽었어요..pem 결과 PKCS8-unencrypted로 정상적으로 처리됩니다.이는 파일이 PEM 형식이 아님을 의미합니다.PEM 형식에는 적어도 유효한 대시 BEGIN 행과 대시 END 행이 필요합니다.이 행이 삭제되지 않으면 de-base64가 실패하거나 잘못됩니다(일부 PEM 형식에는 822 스타일의 헤더가 있어 처리해야 합니다).

  2. 은 BouncyCastle을 것 만, 제 에는 BouncyCastle은 .PKCS8Generator'''만 받는 ''RSAPrivateKey 것은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」JcaPKCS8Generator (RSAPrivateKey implements PrivateKey, OutputEncryptor=null)(즉, 서로 다르지만 관련된 클래스와 하나의 인수가 아닌 두 개의 인수).

  3. PemWriter, 밑에 under at the the the the the를 보기 전에 플러시하지 않았다그리고 그 밑에 있는 것을 보기 전에 플래시하지 않았습니다.StringWriter결과적으로.writer.toString().getBytes()빈 또는 배열입니다.이 배열은 빈 배열 또는 제로 길이의 배열입니다.JSch이치노

하고 내하여 #2를 호출하고 #3을 합니다.JSch를 경유하지 JGit나한텐 효과가 있어

그러니 PuTTYgen에서 같은 문제를 해결하도록 하세요.

여기에 이미지 설명 입력

1) PuTTYgen을 엽니다.

  1. "로드"를 누르고 개인 키를 선택합니다.

여기에 이미지 설명 입력

3) "Conversions" -> 를 눌러 첫 번째 옵션 "Export OPENSH key" 를 선택합니다.

여기에 이미지 설명 입력

  1. 파일로 저장(포맷 불필요)하여 사용

아래 헤더를 피하기 위해 다음 키로 키를 생성해야 합니다.

-C "any-comment"

개인 키에서 제거되는 헤더:

Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,3551DFC375229D5758289E8D366082FE

남기기만

 -----BEGIN RSA PRIVATE KEY-----
YOUR_KEY_HERE
-----END RSA PRIVATE KEY-----

언급URL : https://stackoverflow.com/questions/53134212/invalid-privatekey-when-using-jsch

반응형