Java/Kotlin 以 JCE 密钥对实例和 OpenSSH 格式输出 Ed25519 密钥对
Java/Kotlin Output Ed25519 keypair as both JCE KeyPair instance and in OpenSSH format
我正在使用 BouncyCastle 库在我的 Kotlin 应用程序中生成 Ed25519 密钥对,并且有两个要求很容易单独实现,但似乎很难一前一后地实现:
- 提供密钥对作为 JCE
KeyPair
instance 用于第三方 SSH 库
- 以 OpenSSH .pub 格式提供 public 密钥,供用户复制并粘贴到 git 存储库提供商,例如 GitHub(即
ssh-ed25519 <encoded key> <comment>
)
我有两个使用 BouncyCastle 生成密钥的选项,每个选项只满足其中一个要求。
直接使用BouncyCastle生成器生成
val generator = Ed25519KeyPairGenerator()
generator.init(Ed25519KeyGenerationParameters(SecureRandom()))
val pair = generator.generateKeyPair()
这给了我一个包含 Ed25519PublicKeyParameters
的密钥,这使得使用 BouncyCastle 提供的 OpenSSHPublicKeyUtil
获取 OpenSSH .pub 格式非常容易:
"ssh-ed25519 " + toBase64(OpenSSHPublicKeyUtil.encodePublicKey(publicKey))
...但是没有明显的方法可以从这里进入 JCE KeyPair
。 BouncyCastle JCE 实现似乎使用 BCEdDSAPublicKey
和 BCEdDSAPrivateKey
作为包装器 类 正是为了这个目的,但它们的构造函数是包私有的。
使用 BouncyCastle 作为 JCE 安全提供程序生成
Security.addProvider(BouncyCastleProvider())
val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(EdDSAParameterSpec.Ed25519, BouncyCastleProvider.PROVIDER_NAME)
keyPairGenerator.initialize(EdDSAParameterSpec(EdDSAParameterSpec.Ed25519), SecureRandom())
val pair = keyPairGenerator.generateKeyPair()
这给了我正在寻找的 JCE KeyPair
,但没有明显的方法可以将它转换为 OpenSSH .pub 格式。 this RSA-specific question 中的答案都只支持 DSA/RSA,或者建议似乎也无法处理 Ed25519 密钥的库。我试过:
- Apache SSHD
- SSHJ
- 杰施
我认为我需要的
以下任意一项:
- 一种从 BouncyCastle 的
AsymmetricCipherKeyPair
转换为 JCE KeyPair
的方法
- 一种从
BCEdDSAPublicKey
包装器获取 Ed25519PublicKeyParameters
实例的方法,这样我就可以使用 BouncyCastle 的 OpenSSH 实用程序方法
- 从
KeyPair
以 OpenSSH 格式 输出 BouncyCastle 生成的 Ed25519 public 密钥的另一种方法
- 另一个 way/library 生成一个 Ed25519 密钥对来支持我的两个要求
使用反射进行黑客攻击(包装到扩展 属性 的 getter 中),遵循方式 #2(从 BCEdDSAPublicKey
获取 Ed25519PublicKeyParameters
实例):
val BCEdDSAPublicKey.pubKey
get() = BCEdDSAPublicKey::class.declaredMemberProperties
.find { it.returnType.javaType == AsymmetricKeyParameter::class.java }!!
.apply { isAccessible = true }
.get(this) as AsymmetricKeyParameter
我正在使用 BouncyCastle 库在我的 Kotlin 应用程序中生成 Ed25519 密钥对,并且有两个要求很容易单独实现,但似乎很难一前一后地实现:
- 提供密钥对作为 JCE
KeyPair
instance 用于第三方 SSH 库 - 以 OpenSSH .pub 格式提供 public 密钥,供用户复制并粘贴到 git 存储库提供商,例如 GitHub(即
ssh-ed25519 <encoded key> <comment>
)
我有两个使用 BouncyCastle 生成密钥的选项,每个选项只满足其中一个要求。
直接使用BouncyCastle生成器生成
val generator = Ed25519KeyPairGenerator()
generator.init(Ed25519KeyGenerationParameters(SecureRandom()))
val pair = generator.generateKeyPair()
这给了我一个包含 Ed25519PublicKeyParameters
的密钥,这使得使用 BouncyCastle 提供的 OpenSSHPublicKeyUtil
获取 OpenSSH .pub 格式非常容易:
"ssh-ed25519 " + toBase64(OpenSSHPublicKeyUtil.encodePublicKey(publicKey))
...但是没有明显的方法可以从这里进入 JCE KeyPair
。 BouncyCastle JCE 实现似乎使用 BCEdDSAPublicKey
和 BCEdDSAPrivateKey
作为包装器 类 正是为了这个目的,但它们的构造函数是包私有的。
使用 BouncyCastle 作为 JCE 安全提供程序生成
Security.addProvider(BouncyCastleProvider())
val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance(EdDSAParameterSpec.Ed25519, BouncyCastleProvider.PROVIDER_NAME)
keyPairGenerator.initialize(EdDSAParameterSpec(EdDSAParameterSpec.Ed25519), SecureRandom())
val pair = keyPairGenerator.generateKeyPair()
这给了我正在寻找的 JCE KeyPair
,但没有明显的方法可以将它转换为 OpenSSH .pub 格式。 this RSA-specific question 中的答案都只支持 DSA/RSA,或者建议似乎也无法处理 Ed25519 密钥的库。我试过:
- Apache SSHD
- SSHJ
- 杰施
我认为我需要的
以下任意一项:
- 一种从 BouncyCastle 的
AsymmetricCipherKeyPair
转换为 JCEKeyPair
的方法
- 一种从
BCEdDSAPublicKey
包装器获取Ed25519PublicKeyParameters
实例的方法,这样我就可以使用 BouncyCastle 的 OpenSSH 实用程序方法 - 从
KeyPair
以 OpenSSH 格式 输出 BouncyCastle 生成的 Ed25519 public 密钥的另一种方法
- 另一个 way/library 生成一个 Ed25519 密钥对来支持我的两个要求
使用反射进行黑客攻击(包装到扩展 属性 的 getter 中),遵循方式 #2(从 BCEdDSAPublicKey
获取 Ed25519PublicKeyParameters
实例):
val BCEdDSAPublicKey.pubKey
get() = BCEdDSAPublicKey::class.declaredMemberProperties
.find { it.returnType.javaType == AsymmetricKeyParameter::class.java }!!
.apply { isAccessible = true }
.get(this) as AsymmetricKeyParameter