如何从先前生成的 ECDSA 编码密钥对构造私钥?

K.O*_*.Os 5 android cryptography bouncycastle kotlin ecdsa

生成私钥如下:

    fun getKeyPair(): Pair<ByteArray, ByteArray> {
        Security.addProvider(provider)
        val generator = KeyPairGenerator.getInstance("ECDSA")
        val ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1")
        generator.initialize(ecSpec)
        val keyPair = generator.generateKeyPair()
        val publicKey = keyPair.public as ECPublicKey
        val privateKey = keyPair.private
        return Pair(publicKey.q.getEncoded(true), privateKey.getEncoded())
    }
Run Code Online (Sandbox Code Playgroud)

公钥可以像这样再次重建:

    Security.addProvider(...spongy castle provider)
    val ecSpecs = ECNamedCurveTable.getParameterSpec("secp256r1")
    val q = ecSpecs.curve.decodePoint(publicKeyEncoded)
    val pubSpec = ECPublicKeySpec(q, ecSpecs)
    val keyFactory = KeyFactory.getInstance("ECDSA")
    val generatedPublic = keyFactory.generatePublic(pubSpec)
Run Code Online (Sandbox Code Playgroud)

如何同时从字节重建私钥?

更新:

此代码在实际应用程序中运行良好,但在 JUnit 测试中则不然:

val keyFactory = KeyFactory.getInstance("ECDSA")
val privSpec = PKCS8EncodedKeySpec(privateEncoded)
val generatedPrivate = keyFactory.generatePrivate(privSpec)
Run Code Online (Sandbox Code Playgroud)

在 JUnit 测试中我收到此错误:

java.security.spec.InvalidKeySpecException: encoded key spec not recognised
Run Code Online (Sandbox Code Playgroud)

我的私钥编码字节大小为 150 字节。

Kis*_*kae 4

由于密钥是使用标准编码的Key.getEncoded(),因此以下标准解决方案应该有效:

val keyFactory = KeyFactory.getInstance("EC")
val privSpec = PKCS8EncodedKeySpec(privateEncoded)
val generatedPrivate = keyFactory.generatePrivate(privSpec)
Run Code Online (Sandbox Code Playgroud)

编码密钥应包含重建私钥所需的所有信息,而无需指定其他参数,就像您需要为简化的公钥所做的那样。