如何生成33字节的压缩NIST P-256公钥? [英] How to generate 33-byte compressed NIST P-256 public key?

查看:999
本文介绍了如何生成33字节的压缩NIST P-256公钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要生成这样的公共密钥,并对字节进行附加签名(这将包括此先前生成的密钥)

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

我需要构造以下字节: ASN.1前缀+(33字节压缩NIST P-256公钥)的签名

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

ECDSA规范:

●曲线:

NIST P-256,也称为secp256r1和prime256v1(openssl)

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

●签名格式 ASN.1. ECDSA签名的r和s值必须为正 整数,并进行DER编码.

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

Android中是否有API可以执行此过程?那我怎么用呢?

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

我尝试过的:

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

在这里-编码的公共密钥的长度为90个字节,我想我希望它为33个字节

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

推荐答案

以压缩格式对Bouncy Castle椭圆曲线公钥进行编码:

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)

您未提供有关如何对密钥进行签名和对签名进行编码的所有必要详细信息,但我最好的猜测是在公钥上使用标准编码的标准ECDSA签名:

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

这将使用SHA256哈希公钥,使用ECDSA对其进行签名并进行格式化,并将其序列化为ASN.1结构ECDSASignature的DER编码.

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
}

rs将为正整数,并使用DER编码.还有其他方法,但这是最常用的方法(唯一的其他常见ECDSA签名格式是用零填充r和s并将它们串联).

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).

这篇关于如何生成33字节的压缩NIST P-256公钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆