0

我正在使用BouncyCastle库在我的 Kotlin 应用程序中生成 Ed25519 密钥对,并且有两个要求很容易单独实现,但似乎很难同时完成:

  • 提供密钥对作为JCEKeyPair实例以与第三方 SSH 库一起使用
  • 提供 OpenSSH .pub 格式的公钥供用户复制并粘贴到 git 存储库提供程序,例如 GitHub(即ssh-ed25519 <encoded key> <comment>

我有两个使用 BouncyCastle 生成密钥的选项,每个选项都使这些要求中的一个变得容易。

使用 BouncyCastle 生成器直接生成

val generator = Ed25519KeyPairGenerator()
generator.init(Ed25519KeyGenerationParameters(SecureRandom()))
val pair = generator.generateKeyPair()

这给了我一个包含 的密钥,这使得使用BouncyCastle 提供Ed25519PublicKeyParameters的 OpenSSH .pub 格式变得非常容易:OpenSSHPublicKeyUtil

"ssh-ed25519 " + toBase64(OpenSSHPublicKeyUtil.encodePublicKey(publicKey))

...但是没有明显的方法可以KeyPair从这里到达 JCE。BouncyCastle JCE 实现似乎使用BCEdDSAPublicKeyBCEdDSAPrivateKey作为包装类正是为了这个目的,但它们的构造函数是包私有的。

使用 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 格式。这个 RSA-specific question中的答案都只支持 DSA/RSA,或者建议的库似乎也无法处理 Ed25519 密钥。我试过了:

  • 阿帕奇 SSHD
  • SSHJ
  • Jsch

我认为我需要什么

任何一项:

  • 一种从 BouncyCastle 转换AsymmetricCipherKeyPair为 JCE的方法KeyPair
  • 一种Ed25519PublicKeyParameters从包装器中获取实例的方法,BCEdDSAPublicKey以便我可以使用 BouncyCastle 的 OpenSSH 实用程序方法
  • KeyPair从OpenSSH 格式输出 BouncyCastle 生成的 Ed25519 公钥的另一种方法
  • 生成支持我的两个要求的 Ed25519 密钥对的另一种方式/库
4

1 回答 1

1

使用反射(包装在扩展属性的 getter 中)进行破解,遵循方式 #2(Ed25519PublicKeyParameters从 a 获取实例BCEdDSAPublicKey):

val BCEdDSAPublicKey.pubKey
    get() = BCEdDSAPublicKey::class.declaredMemberProperties
        .find { it.returnType.javaType == AsymmetricKeyParameter::class.java }!!
        .apply { isAccessible = true }
        .get(this) as AsymmetricKeyParameter
于 2020-11-13T10:53:50.857 回答