提问人:Evgenii Sokolov 提问时间:10/17/2023 更新时间:10/18/2023 访问量:101
如何使用 java BouncyCastle 创建带有密码的 OpenSSH 私钥
How to create OpenSSH private key with password using java BouncyCastle
问:
使用非密码加密私钥创建 OpenSSH 密钥的简单方法:
AsymmetricCipherKeyPairGenerator gen = new Ed25519KeyPairGenerator();
gen.init(new KeyGenerationParameters(new SecureRandom(), 255));
AsymmetricCipherKeyPair kp = gen.generateKeyPair();
byte[] bprv = OpenSSHPrivateKeyUtil.encodePrivateKey(kp.getPrivate());
StringWriter sw = new StringWriter();
PemWriter w = new PemWriter(sw);
w.writeObject(new PemObject("OPENSSH PRIVATE KEY", bprv)); w.close();
String privateKey = sw.toString(); sw.close();
System.out.println(privateKey);
byte[] bpub = OpenSSHPublicKeyUtil.encodePublicKey(kp.getPublic());
sw = new StringWriter();
w = new PemWriter(sw);
w.writeObject(new PemObject("SSH2 PUBLIC KEY", bpub)); w.close();
String publicKey = sw.toString(); sw.close();
但是如何创建使用密码加密的私钥呢?可能吗?
答:
1赞
Topaco
10/18/2023
#1
如果您找不到使用 BouncyCastle 导出加密的 OpenSSH 密钥的方法:允许导出加密的 OpenSSH 密钥的库是 sshtools/maverick-synergy。
生成 Ed25519 密钥对并导出私钥加密密钥和公钥的示例:
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import com.sshtools.common.publickey.SshKeyUtils;
import com.sshtools.common.ssh.components.SshKeyPair;
import com.sshtools.common.ssh.components.jce.JCEAlgorithms;
import com.sshtools.common.ssh.components.jce.SshEd25519PrivateKeyJCE;
import com.sshtools.common.ssh.components.jce.SshEd25519PublicKeyJCE;
...
// Create Ed25519 key pair
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(JCEAlgorithms.ED25519);
KeyPair kp = keyGen.generateKeyPair();
SshKeyPair pair = new SshKeyPair();
pair.setPrivateKey(new SshEd25519PrivateKeyJCE(kp.getPrivate()));
pair.setPublicKey(new SshEd25519PublicKeyJCE(kp.getPublic()));
// Export
System.out.println(SshKeyUtils.getFormattedKey(pair, "my passphrase"));
System.out.println(SshKeyUtils.getFormattedKey(pair.getPublicKey(), "my comment"));
替换为以下示例输出:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDN
3FuF2G77g48ktctKG3NTAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIO+e
PM91Qbd6b6bF8sKfOJiox19K1llf8UwUbUayPmRHAAAAkD7rMYeeAKeyiwEU1uy2
iNsXTTWHR2jK2abcQ3Qndw1lQBmM+QfmdefnoN4HToSuSVzybaLBRoHl5vybFq74
5JaZ9ZQitXBrBLX91imjGmHDPr/nOYWo57Yuh05gPnx96MZHo61Ze6HNWhZ73xBT
6ve7YAxCDO8LjGjyC17k2/0HMcPOwbV8J39f5KTeXNf6vA==
-----END OPENSSH PRIVATE KEY-----
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO+ePM91Qbd6b6bF8sKfOJiox19K1llf8UwUbUayPmRH my comment
OpenSSH私钥的格式在这里描述(更详细,特别是关于 加密逻辑,在这里)。如果加密的 OpenSSH 私钥是 Base64 解码的,则可以识别各个部分:
6f70656e7373682d6b65792d763100 "openssh-key-v1" + 0x00
0000000a 6165733235362d637472 length: 0x0a, "aes256-ctr"
00000006 626372797074 length: 0x06, "bcrypt"
00000018 00000010cddc5b85d86efb838f24b5cb4a1b735300000010 total length: 0x18, salt length: 0x10 + <salt, here 0xcddc5b85d86efb838f24b5cb4a1b7353> + <rounds, here 0x10>
00000001
00000033 0000000b7373682d6564323535313900000020ef9e3ccf7541b77a6fa6c5f2c29f3898a8c75f4ad6595ff14c146d46b23e6447
00000090 3eeb31879e00a7b28b0114d6ecb688db174d35874768cad9a6dc437427770d6540198cf907e675e7e7a0de074e84ae495cf26da2c14681e5e6fc9b16aef8e49699f59422b5706b04b5fdd629a31a61c33ebfe73985a8e7b62e874e603e7c7de8c647a3ad597ba1cd5a167bdf1053eaf7bb600c420cef0b8c68f20b5ee4dbfd0731c3cec1b57c277f5fe4a4de5cd7fabc
第二行包含加密算法的说明,第三行包含所用密钥派生函数 (KDF) 的说明,第四行包含 KDF 选项的说明。
在未加密密钥的情况下,算法和 KDF 的行各0x000000046e6f6e65(即长度:0x04 + “none”),带有 KDF 选项的行为 0x00000000(即长度:0)。
对于生成的密钥,这些值是不同的,并表明密钥在 CTR 模式下使用 AES-256 加密,并且 bcrypt(更准确地说,是 bcrypt 的 OpenSSH 特定变体)作为 KDF 应用。
评论