如何以Putty或Puttygen可读格式导出(PKCS#8?)私钥?

时间:2016-04-05 05:21:49

标签: java putty ssh-keys

我正在编写一个使用AWS Java API创建新的Amazon Web Services服务器的工具。创建服务器时,必须指定AWS在您的帐户中存储的公钥中使用的SSH密钥对。您可以自己生成密钥对并导入公钥,也可以让AWS生成密钥对并下载私钥。

我正在尝试自己生成密钥对,将公钥导入AWS,使用新注册的密钥对条目启动新服务器并在本地保存私钥。然后我想使用私有密钥将Putty用于ssh到我的新服务器,可能首先通过Puttygen将其转换为。

到目前为止,我已经生成了密钥对,成功将公钥导入AWS并启动了新服务器。但是,我不能为我的生活似乎能够以任何格式导出私钥,Putty或Puttygen会接受。

这是我生成密钥对并保存私钥的代码:

SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
random.nextBytes(new byte[]{}); //toss out the first result to ensure it seeds randomly from the system.

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(KEY_LENGTH, random);
KeyPair keyPair = keyGen.genKeyPair();

BASE64Encoder encoder = new BASE64Encoder();

FileOutputStream out =  null;
File keyPath = new File(_keyStorageDir, "private.pem");
try
{
    out = new FileOutputStream(keyPath);
    out.write(encoder.encode(keyPair.getPrivate().getEncoded()).getBytes());
}
finally
{
    if(out != null)
        out.close();
}

然而,当我尝试在PuttyGen中导入密钥时,我得到“无法加载密钥(不是私钥)”。如果我尝试添加----- BEGIN PRIVATE KEY -----及其相应的页脚我得到“无法加载私钥(无法识别的密钥类型)。如果我尝试RSA PRIVATE KEY我得到”无法加载私有密钥(ASN.1解码失败)“。

调用keyPair.getPrivate().getFormat()会产生“PKCS#8”。虽然我已经找到了使用OpenSSL工具从该格式转换为pem格式的引用,但我还没有找到任何关于如何在Java中实际使用它的方法。

如何以pem格式导出密钥以便Puttygen可以读取它?

2 个答案:

答案 0 :(得分:1)

现在不需要FYI或其他任何人,Puttygen也会进口:

  • OpenSSH使用的格式(一直到最近,默认情况下仍然如此) 这是OpenSSL 在实施PKCS#8之前定义的原始又名“遗留”格式 - 对于RSA,这是PKCS#1,相当于PKCS#8的 part ;

  • 或'商业'SSH.COM使用的格式,与PKCS#8完全不同。

因此你可以RSAPrivateKey.getEncoded()获取PKCS#8,解析PKCS#8的字节以获取PKCS#1部分,并解析base64 / PEMify。这实际上是您使用openssl rsa -in pkcs8 -out rsa找到的建议。

但你找到的方法(使用Bouncy)更容易。对于DSA或ECDSA,如果你想使用它们会更加如此 (最好只支持Java 8+,支持超过1024的DSA大小,符合186-3和当前的良好做法)。

答案 1 :(得分:0)

啊哈!

诀窍是使用Bouncycastle的pem处理类。这是一个有效的演示:

import org.bouncycastle.openssl.jcajce.JcaPEMWriter;

import java.io.File;
import java.io.FileWriter;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;

public class Main
{
    public static final int KEY_LENGTH = 2048;

    public static void main(String[] args) throws Exception
    {
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
        random.nextBytes(new byte[]{}); //toss out the first result to ensure it seeds randomly from the system.

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(KEY_LENGTH, random);
        java.security.KeyPair keyPair = keyGen.genKeyPair();

        System.out.println("public format: " + keyPair.getPublic().getFormat());
        System.out.println("public algorithm: " + keyPair.getPublic().getAlgorithm());

        System.out.println("private format: " + keyPair.getPrivate().getFormat());
        System.out.println("private algorithm: " + keyPair.getPrivate().getAlgorithm());

        JcaPEMWriter writer =  null;
        File keyDir = new File("C:/misc/test_key");

        try
        {
            writer = new JcaPEMWriter(new FileWriter(new File(keyDir, "private_bc.pem")));
            writer.writeObject(keyPair.getPrivate());    
        }
        finally
        {
            if(writer != null)
                writer.close();
        }    
    }
}

Puttygen在没有投诉的情况下打开生成的私钥!