如何使用Java BouncyCastle创建带密码的OpenSSH私钥
带密码加密的OpenSSH私钥生成实现
当然可以实现,基于你提供的无密码密钥生成代码,只需要修改私钥编码的步骤,用BouncyCastle支持加密的OpenSSHPrivateKeyUtil.encodePrivateKey重载方法就行。OpenSSH支持多种加密算法,比如当前默认的chacha20-poly1305@openssh.com或者兼容性更好的aes256-cbc,下面是具体的实现代码:
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; import org.bouncycastle.openssh.OpenSSHPrivateKeyUtil; import org.bouncycastle.openssh.OpenSSHPublicKeyUtil; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; import java.io.StringWriter; import java.security.SecureRandom; public class EncryptedSSHKeyGenerator { public static void main(String[] args) throws Exception { // 生成Ed25519密钥对,和无密码版本步骤一致 AsymmetricCipherKeyPairGenerator gen = new Ed25519KeyPairGenerator(); gen.init(new KeyGenerationParameters(new SecureRandom(), 255)); AsymmetricCipherKeyPair kp = gen.generateKeyPair(); Ed25519PrivateKeyParameters privateKeyParams = (Ed25519PrivateKeyParameters) kp.getPrivate(); // 配置加密参数:用OpenSSH默认的ChaCha20-Poly1305加密 String encryptionAlgorithm = "chacha20-poly1305@openssh.com"; char[] password = "your-strong-password-here".toCharArray(); // 替换成你的密码 SecureRandom random = new SecureRandom(); byte[] salt = new byte[16]; // ChaCha20-Poly1305需要16字节随机盐 random.nextBytes(salt); int kdfIterations = 10000; // KDF迭代次数,建议不低于10000 // 加密并编码私钥 byte[] encryptedPrivateKeyBytes = OpenSSHPrivateKeyUtil.encodePrivateKey( privateKeyParams, encryptionAlgorithm, password, salt, kdfIterations ); // 写入PEM格式,和无密码版本步骤一致 StringWriter sw = new StringWriter(); try (PemWriter w = new PemWriter(sw)) { w.writeObject(new PemObject("OPENSSH PRIVATE KEY", encryptedPrivateKeyBytes)); } String encryptedPrivateKey = sw.toString(); System.out.println("加密后的私钥:\n" + encryptedPrivateKey); // 公钥生成完全和无密码版本一样 byte[] bpub = OpenSSHPublicKeyUtil.encodePublicKey(kp.getPublic()); sw = new StringWriter(); try (PemWriter w = new PemWriter(sw)) { w.writeObject(new PemObject("SSH2 PUBLIC KEY", bpub)); } String publicKey = sw.toString(); System.out.println("\n公钥:\n" + publicKey); } }
关键注意事项
- 加密算法选择:优先用
chacha20-poly1305@openssh.com,这是OpenSSH现在的默认加密方式,安全性更高;如果要兼容旧版本服务器,再考虑aes256-cbc - 密码与参数设置:密码要足够复杂,盐必须随机生成(避免彩虹表攻击),迭代次数建议设置为10000以上,次数越高安全性越好,但生成密钥的速度会稍慢
- 类型转换:需要把生成的私钥转换为具体的实现类(比如
Ed25519PrivateKeyParameters),否则加密方法无法正确处理
内容的提问来源于stack exchange,提问作者Evgenii Sokolov
相关产品推荐
相关产品推荐

