Java >> Java tutorial >  >> Tag >> private

Udledning af ECDSA offentlig nøgle fra privat nøgle

Så efter et stykke tid fandt jeg ud af en løsning og besluttede at poste den, hvis nogen andre har samme problem som mig:

KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
    ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256k1");

    ECPoint Q = ecSpec.getG().multiply(((org.bouncycastle.jce.interfaces.ECPrivateKey) this.privateKey).getD());

    ECPublicKeySpec pubSpec = new ECPublicKeySpec(Q, ecSpec);
    PublicKey publicKeyGenerated = keyFactory.generatePublic(pubSpec);
    this.publicKey = publicKeyGenerated;

EDIT:Fjernede koden, der afkoder ECPoint i henhold til @MaartenBodewes kommentar.


Med udgangspunkt i det tidligere svar kan man udvide dette til det tilfælde, at det eneste, man får, er en privat nøgle, der opfylder BCECPrivateKey-grænsefladen:

DerivePubKeyFromPrivKey(BCECPrivateKey definingKey, Provider provider) {

    KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);

    BigInteger d = definingKey.getD();
    org.bouncycastle.jce.spec.ECParameterSpec ecSpec = 
    definingKey.getParameters();
    ECPoint Q = definingKey.getParameters().getG().multiply(d);

    org.bouncycastle.jce.spec.ECPublicKeySpec pubSpec = new 
    org.bouncycastle.jce.spec.ECPublicKeySpec(Q, ecSpec);
    PublicKey publicKeyGenerated = keyFactory.generatePublic(pubSpec);
    return publicKeyGenerated;
}

Jeg kom her med det samme problem i Kotlin, så hvis det hjælper nogen, er det sådan, jeg udledte PublicKey fra en ECDSA PrivateKey i Kotlin. Denne kode er baseret på Lev Knoblocks Java-svar og derefter prøve-og-fejl, indtil det virkede.

I mit tilfælde vidste jeg, at min nøgle brugte secp256k1 kurve, så jeg kunne hårdkode den del. Jeg gad ikke lære at generalisere det til andre kurver.

import java.security.KeyFactory
import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo
import org.bouncycastle.jce.ECNamedCurveTable
import org.bouncycastle.jce.interfaces.ECPrivateKey
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec
import org.bouncycastle.jce.spec.ECPublicKeySpec
import org.bouncycastle.math.ec.ECPoint
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter
import org.bouncycastle.openssl.PEMParser

fun getECPrivateKeyFromPEM(privatePem: String): ECPrivateKey {
    val pemParser = PEMParser(privatePem.reader())
    val privateKeyInfo = pemParser.readObject() as PrivateKeyInfo
    return JcaPEMKeyConverter().getPrivateKey(privateKeyInfo) as ECPrivateKey
}

fun getKeyPairFromECPrivateKey(privateKey: ECPrivateKey): KeyPair {
    val keyFactory: KeyFactory = KeyFactory.getInstance("ECDSA", "BC")
    val spec: ECNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("secp256k1")
    val Q: ECPoint = spec.getG().multiply(privateKey.getD())
    val publicKey: PublicKey = keyFactory.generatePublic(ECPublicKeySpec(Q, spec))
    return KeyPair(publicKey, privateKey)
}

Og her er min testsele:

import java.io.StringWriter
import org.bouncycastle.openssl.jcajce.JcaPEMWriter

fun main() {
    val privatePem = """
       |-----BEGIN PRIVATE KEY-----
       |MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg55EMdhNJX+YN/bjN
       |Eof91oKqEqD0QidEsRMhHBwSRjShRANCAARnSFpE0LDugORBWlSJz0Zf9e0mR9s6
       |tlxSeo1Nbd2vv9LDedm+l/CfZpbyYvPm49DAKDhkUHFIVDd2SsiPrRa7
       |-----END PRIVATE KEY-----
    """.trimMargin()
    val privateKey: ECPrivateKey = getECPrivateKeyFromPEM(privatePem)
    val pair: KeyPair = getKeyPairFromECPrivateKey(privateKey)
    val pems: String = StringWriter().use {
        val pemWriter = JcaPEMWriter(it)
        pemWriter.writeObject(pair.getPublic())
        pemWriter.writeObject(pair.getPrivate())
        pemWriter.flush()
        it.toString()
    }
    println(pems)
}

Dette udskriver:

-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEcE4HMAHLDvPr6xHKsjhPXJzTdxLlRRR8
BfYnI2TGb0QLTFyyXm13CeYiLnxbkGhSvz9ZRo0zGQygKPVpgiThSw==
-----END PUBLIC KEY-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIOeRDHYTSV/mDf24zRKH/daCqhKg9EInRLETIRwcEkY0oAoGCCqGSM49
AwEHoUQDQgAEZ0haRNCw7oDkQVpUic9GX/XtJkfbOrZcUnqNTW3dr7/Sw3nZvpfw
n2aW8mLz5uPQwCg4ZFBxSFQ3dkrIj60Wuw==
-----END EC PRIVATE KEY-----

Java tag