How to construct private key from generated previo

2019-07-03 09:32发布

问题:

Having generated the private key like this:

    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())
    }

The public key can be reconstructed again like this:

    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)

How it is possible to reconstruct private key from bytes also along with this?

UPDATE:

This code works well in actual app but it doesnt in JUnit testing:

val keyFactory = KeyFactory.getInstance("ECDSA")
val privSpec = PKCS8EncodedKeySpec(privateEncoded)
val generatedPrivate = keyFactory.generatePrivate(privSpec)

In JUnit test I am getting this error:

java.security.spec.InvalidKeySpecException: encoded key spec not recognised

My private key as encoded bytes has 150 bytes size.

回答1:

Since the key is encoded using the standard Key.getEncoded(), the following standard solution should work:

val keyFactory = KeyFactory.getInstance("EC")
val privSpec = PKCS8EncodedKeySpec(privateEncoded)
val generatedPrivate = keyFactory.generatePrivate(privSpec)

The encoded key should contain all the required information to rebuild the private key without specifying additional parameters like you need to do for the reduced public key.