首页  编辑  

Java中生成SSH Key密钥

Tags: /Java/   Date Created:
基于JSCH library 生成ssh key对(private key & public key),用于配置SFTP免密登录
  • 添加JSCH依赖
<!-- JSCH -->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>
  • source code
代码中有一些Util类,或者DTO类没有写进去,自动忽略即可
package xxx;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.KeyPair;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Date;

@Service
public class SSHKeyGeneratorServiceImpl implements SSHKeyGeneratorService {

  private static final int KEY_SIZE = 2048;

  public String generateSSHKey(SftpKeyDTO dto) {
    String keyMagic = SftpKeyUtil.genRandomMagic();
    KeyPair keyPair;
    String priKeyFileName;

    try {
      keyPair = KeyPair.genKeyPair(new JSch(), KeyPair.RSA, KEY_SIZE);
      keyPair.writePrivateKey(new FileOutputStream(getPriKeyFile(dto.getid())), keyMagic.getBytes(StandardCharsets.UTF_8));
      keyPair.writePublicKey(new FileOutputStream(getPubKeyFile(dto.getid())), "");
    } catch (Exception e) {
      throw Exceptions.exception(ErrorCodeEnum.GENERATE_SSH_KEY_FAIL, e);
    }

    return getPublicKeyContext(keyPair);
  }

// 这里是从JSCH源码中copy出来,因为我需要一个public key字符串而不是文件,你可以忽略,
// 如果你也需要得到一个public key的字符串,而不是文件,可以参考源码keyPair.writePublicKey方法中是怎么写内容的,自然就能找到这个内容是怎么生成的代码
  private String getPublicKeyContext(KeyPair keyPair) {
    byte[] pubBlob=keyPair.getPublicKeyBlob();
    byte[] pub= SftpKeyUtil.toBase64(pubBlob, 0, pubBlob.length);
    String result = "ssh-rsa ";
    result = result + new String(pub, 0, pub.length, StandardCharsets.UTF_8);
    return result;
  }

  private File getPriKeyFile(String id) throws IOException {
    return generateFile(id, "_pri");
  }

  private File getPubKeyFile(String id) throws IOException {
    return generateFile(id, "_pub");
  }
  
  private File generateFile(String id, String keyType) throws IOException {
    String filename = id + keyType;
    int index = 1;
    while (true) {
      File keyFile = new File(PathConstant.getKeysPath(), filename);
      if (keyFile.exists()) {
        filename = id + keyType + (++index);
        continue;
      }
      if (keyFile.createNewFile()) {
        return keyFile;
      }
    }
  }
}