【问题标题】:How can I export a (PKCS#8?) private key in Putty or Puttygen readable format?如何以 Putty 或 Puttygen 可读格式导出(PKCS#8?)私钥?
【发布时间】:2016-04-12 17:31:27
【问题描述】:

我正在编写一个工具来使用 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 可以读取?

【问题讨论】:

    标签: java putty ssh-keys


    【解决方案1】:

    啊哈!

    诀窍是使用 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 毫无怨言地打开生成的私钥!

    【讨论】:

      【解决方案2】:

      现在不需要,但仅供参考或其他任何人,Puttygen 进口:

      • OpenSSH 使用的格式(一直到最近,并且仍然默认) 这是 OpenSSL 实现 PKCS#8 之前定义的原始 aka 'legacy' 格式 -- 对于 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 和当前的良好做法)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-04
        • 2016-11-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-26
        • 1970-01-01
        • 2016-09-30
        • 1970-01-01
        相关资源
        最近更新 更多