Java 如何以Putty或Puttygen可读格式导出(PKCS#8?)私钥?
我正在编写一个工具,使用AWS Java API创建新的Amazon Web服务服务器。创建服务器时,必须指定AWS存储在帐户中的公钥中要使用的SSH密钥对。您可以自己生成密钥对并导入公钥,也可以让AWS生成密钥对并下载私钥 我试图自己生成密钥对,将公钥导入AWS,使用新注册的密钥对条目启动新服务器,并在本地保存私钥。然后我想使用Putty将ssh连接到我的新服务器中,使用私钥,可能首先通过Puttygen将其转换 到目前为止,我已经生成了我的密钥对,成功地将公钥导入AWS并启动了一个新服务器。然而,我无法以Putty或Puttygen可以接受的任何格式导出私钥 以下是生成密钥对并保存私钥的代码:Java 如何以Putty或Puttygen可读格式导出(PKCS#8?)私钥?,java,putty,ssh-keys,Java,Putty,Ssh Keys,我正在编写一个工具,使用AWS Java API创建新的Amazon Web服务服务器。创建服务器时,必须指定AWS存储在帐户中的公钥中要使用的SSH密钥对。您可以自己生成密钥对并导入公钥,也可以让AWS生成密钥对并下载私钥 我试图自己生成密钥对,将公钥导入AWS,使用新注册的密钥对条目启动新服务器,并在本地保存私钥。然后我想使用Putty将ssh连接到我的新服务器中,使用私钥,可能首先通过Puttygen将其转换 到目前为止,我已经生成了我的密钥对,成功地将公钥导入AWS并启动了一个新服务器。
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私钥,我会得到“无法加载私钥(ASN.1解码失败)”
调用keyPair.getPrivate().getFormat()
会产生“PKCS#8”。虽然我找到了使用OpenSSL工具将该格式转换为pem格式的参考资料,但我还没有找到任何关于如何在Java中实际实现的信息
如何以pem格式导出密钥,以便Puttygen可以读取它?啊哈
诀窍是使用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毫无怨言地打开生成的私钥!现在不需要,但仅供参考或任何其他人使用,Puttygen导入:
- OpenSSH使用的格式(一直到最近,默认情况下仍然如此) 在OpenSSL实现PKCS#8之前,它定义了哪些原始的aka“遗留”格式 --对于RSA,这是PKCS#1,相当于PKCS#8的一部分
- 或者“商业”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和当前的良好实践)