How to generate 33-byte compressed NIST P-256 public key?

怎甘沉沦 提交于 2019-12-13 03:26:58

问题


I need to generate such public key and do the additional signing of the bytes (which will include this generated previously key)

I need to construct bytes of: ASN.1 prefix + signature of (33-byte compressed NIST P-256 public key)

The signature should be delivered from other defined private key

The ECDSA specifications:

● Curve:

NIST P-256 Otherwise known as secp256r1 and prime256v1 (openssl)

● Signature format ASN.1. The r and s values of the ECDSA signature must be positive integers, and DER-encoded as such.

Is there API in Android to do such process? How can I use it then?

WHAT I've tried:

 try {
        val generator = KeyPairGenerator.getInstance("ECDSA")
        val ecSpec = ECNamedCurveTable
                .getParameterSpec("prime256v1")
        generator.initialize(ecSpec)
        val keyPair = generator.generateKeyPair()

        val privKey = keyPair.private
        val encodedPrivKey = privKey.encoded
        System.out.println(toHex(encodedPrivKey))

        val pubKey = keyPair.public
        val encodedPubKey = pubKey.encoded
        System.out.println(toHex(encodedPubKey))

        val keyFactory = KeyFactory.getInstance("ECDSA")
        val pubKey2 = keyFactory.generatePublic(X509EncodedKeySpec(encodedPubKey))
        if (Arrays.equals(pubKey2.getEncoded(), encodedPubKey)) {
            println("That worked for the public key")
        }

        val privKey2 = keyFactory.generatePrivate(PKCS8EncodedKeySpec(encodedPrivKey))
        if (Arrays.equals(privKey2.getEncoded(), encodedPrivKey)) {
            println("That worked for the private key")
        }

    } catch (e: GeneralSecurityException) {
        throw IllegalStateException(e)
    }

Here - the encoded public key has the lenght of 90 bytes which i guess i want it to be 33 bytes


回答1:


To encode a Bouncy Castle elliptic curve public key in compressed format:

Security.addProvider(BouncyCastleProvider())  

generator = KeyPairGenerator.getInstance("ECDSA")
val ecSpec = ECNamedCurveTable.getParameterSpec("prime256v1")        
generator.initialize(ecSpec)
val keyPair = generator.generateKeyPair()

val publicKey = keyPair.public as org.bouncycastle.jce.interfaces.ECPublicKey
val compressedPublicKey = publicKey.q.getEncoded(true)

You are not including all the necessary details about how to sign the key and encode the signature, but my best guess would be a standard ECDSA signature on the public key with a standard encoding:

val signer = Signature.getInstance("SHA256withECDSA")
signer.initSign(otherPrivateKey)
signer.update(compressedPublicKey)
val signature = signer.sign()

This hashes the public key using SHA256, signs it using ECDSA and formats and serializes it as the DER encoding of the ASN.1 structure ECDSASignature.

ECDSASignature ::= SEQUENCE {
    r   INTEGER,
    s   INTEGER
}

r and s will be positive integers and encoded with DER. There are other ways of doing so, but this is by far the most common way (the only other common ECDSA signature format is just padding r and s with zeroes and concatenating them).



来源:https://stackoverflow.com/questions/53629537/how-to-generate-33-byte-compressed-nist-p-256-public-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!