将 openssh public 密钥转换为 ssh2 (RFC 4716) 格式

Converting openssh public key to ssh2 (RFC 4716) format

主要问题就是这个。解析 openssh public 键以符合 rfc 4716 格式。唯一的问题是,它必须在 java.

使用ssh-keygen,它只是单行命令:

ssh-keygen -e -f openssh_key.pub

不幸的是,我在 Java 中找不到任何其他来源。甚至没有提到转换所需的任何算法或步骤。所有这些都围绕 ssh-keygen 本身的使用展开。当然,我可以使用 java.exec 来调用命令,但那是最坏的情况。


示例 openssh 密钥(已将其保存为代码格式以保留生成的 spaces/new-line):

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDwxgE7D3HYLYddNHLMFK8OfpRwwUSgxiB8fbecvkCUEktSpWikvsWTyCnl5p3uSmsGg/F1lwVPXuuVlQ4VZlYqMuEBEMRF9ADdXWWNxjO/Hd7688ow7ocncxl0xKXsH5Fc9GHvE8yfUh94F8Qm9x8M8Uux+XsNEvPG8KI/QUJWndIsHv+m//3nbEEqUTAlzsyY0mjHW/dPORhXcB5WeGH+cBRAhcp5JGKAq26TOsuNY8H+nrlxX6z03xbUN28HHdXv6uKZfpnVpl6tM0khxbh7F+tLYWeUIZ+nYaDBPINv8Mkd6Duqe/GOLtgVUIR76Adijok4w5oaKlTq27xzMurl kaushik@kaushik-HP

使用 ssh-keygen 解析:

---- BEGIN SSH2 PUBLIC KEY ----
Comment: "2048-bit RSA, converted by kaushik@kaushik-HP from OpenSSH"
AAAAB3NzaC1yc2EAAAADAQABAAABAQDwxgE7D3HYLYddNHLMFK8OfpRwwUSgxiB8fbecvk
CUEktSpWikvsWTyCnl5p3uSmsGg/F1lwVPXuuVlQ4VZlYqMuEBEMRF9ADdXWWNxjO/Hd76
88ow7ocncxl0xKXsH5Fc9GHvE8yfUh94F8Qm9x8M8Uux+XsNEvPG8KI/QUJWndIsHv+m//
3nbEEqUTAlzsyY0mjHW/dPORhXcB5WeGH+cBRAhcp5JGKAq26TOsuNY8H+nrlxX6z03xbU
N28HHdXv6uKZfpnVpl6tM0khxbh7F+tLYWeUIZ+nYaDBPINv8Mkd6Duqe/GOLtgVUIR76A
dijok4w5oaKlTq27xzMurl
---- END SSH2 PUBLIC KEY ----

更新:我已经为有类似需求的任何人创建了一个implementation of the conversion on gist

两种格式的 Base64 数据是相同的——您不需要做任何花哨的事情。在这些格式之间进行转换所需要做的就是 add/remove 换行符(70 个字符)并更改 header/trailer.

请注意,两种格式在 OpenSSH 密钥中都有注释 -- kaushik@kaushik-HP,在 PEM 密钥中以 Comment: 开头的行。两者都是完全可选的,不需要转换。

好吧,我不知道该哭还是该笑,因为我终于找到了我需要的确切功能,以及 JSch library. This was ofcourse after I wrote my own implementation 中用于转换的更多功能。因此,我对 laugh/cry 情况感到进退两难。不过现在,很高兴我在这个过程中学到了一些新东西。

一个使用JSch's KeyPair class的小例子:

生成 private-public 密钥对 (RSA) :

JSch jSch = new JSch();
KeyPair keyPair = KeyPair.genKeyPair(jSch, KeyPair.RSA);

keyPair.writePrivateKey("privateKey"); //store private key in file - 'privateKey'
keyPair.writePublicKey("publicKey");   //store public key in file - 'publickKey'

将 public 密钥转换为 RFC 4716 格式。

keyPair.writeSECSHPublicKey("ssh2Key"); //store ssh2 public key in file - 'ssh2Key'

根据 duskwuff 的回答,这是我为进行转换而编写的代码:

public String convert(String rsaKey){
    String[] keyParts = rsaKey.split("\s"); // header + content + comment
    if(keyParts.length < 2 || !keyParts[0].equals("ssh-rsa"))
        throw new IllegalArgumentException("The key "+rsaKey+" is not a properly formatted RSA key.");
    StringBuilder sb = new StringBuilder("---- BEGIN SSH2 PUBLIC KEY ----\n");
    final int rowLength = 70;
    final String keyContent = keyParts[1];
    for(int i=0; i*rowLength < keyContent.length(); i++){
        sb.append(keyContent, i*rowLength, Math.min((i+1)*rowLength, keyContent.length())).append('\n');
    }
    sb.append("---- END SSH2 PUBLIC KEY ----");
    return sb.toString();
}