Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/178.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何生成33字节压缩NIST P-256公钥?_Android_Kotlin_Cryptography_Bouncycastle_Ecdsa - Fatal编程技术网

Android 如何生成33字节压缩NIST P-256公钥?

Android 如何生成33字节压缩NIST P-256公钥?,android,kotlin,cryptography,bouncycastle,ecdsa,Android,Kotlin,Cryptography,Bouncycastle,Ecdsa,我需要生成这样的公钥,并对字节进行额外的签名(这将包括以前生成的密钥) 我需要构造以下字节: ASN.1前缀+签名(33字节压缩NIST P-256公钥) 签名应该从其他定义的私钥传递 ECDSA规范: ● 曲线: NIST p-256,也称为secp256r1和prime256v1(openssl) ● 签名格式 ASN.1。ECDSA签名的r和s值必须为正值 整数,并按此编码 Android中是否有API来完成这一过程?那我怎么用呢 我所尝试的: try { val gen

我需要生成这样的公钥,并对字节进行额外的签名(这将包括以前生成的密钥)

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

签名应该从其他定义的私钥传递

ECDSA规范:

● 曲线:

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

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

Android中是否有API来完成这一过程?那我怎么用呢

我所尝试的:

 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字节

以压缩格式编码弹性城堡椭圆曲线公钥:

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签名具有标准编码:

val signer = Signature.getInstance("SHA256withECDSA")
signer.initSign(otherPrivateKey)
signer.update(compressedPublicKey)
val signature = signer.sign()
这将使用SHA256散列公钥,使用ECDSA对其进行签名,并将其格式化并序列化为ASN.1结构ECDSASignature的DER编码

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

r
s
将是正整数,并用DER编码。还有其他方法,但这是目前为止最常见的方法(唯一其他常见的ECDSA签名格式就是用零填充r和s并将它们连接起来)。

要以压缩格式对弹性城堡椭圆曲线公钥进行编码:

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签名具有标准编码:

val signer = Signature.getInstance("SHA256withECDSA")
signer.initSign(otherPrivateKey)
signer.update(compressedPublicKey)
val signature = signer.sign()
这将使用SHA256散列公钥,使用ECDSA对其进行签名,并将其格式化并序列化为ASN.1结构ECDSASignature的DER编码

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

r
s
将是正整数,并用DER编码。还有其他方法可以做到这一点,但这是目前为止最常见的方法(唯一其他常见的ECDSA签名格式就是用零填充r和s并将它们连接起来)。

谢谢,如果它涵盖了我在问题中描述的部分:签名格式ASN.1,您能解释更多吗。ECDSA签名的r和s值必须是正整数,并且DER编码为正整数。关于签名,我将使用“SHA256withECDSA”@K.Os,这可能会有所帮助。ASN.1/DER签名格式与X9.62兼容,是Java的默认格式。另一种格式有时称为“平面”签名,因为r和s值没有嵌入到层次结构中。DER编码的ASN.1整数值是有符号的,但如果设置了最高有效位,则数字将填充为零字节,因此结果始终为正。@K.Os我认为linehrr已经正确回答了这个问题。如果他的解决方案不起作用,请再次Ping我。谢谢,如果它涵盖了我在问题中描述的部分:签名格式ASN.1,您能解释更多吗。ECDSA签名的r和s值必须是正整数,并且DER编码为正整数。关于签名,我将使用“SHA256withECDSA”@K.Os,这可能会有所帮助。ASN.1/DER签名格式与X9.62兼容,是Java的默认格式。另一种格式有时称为“平面”签名,因为r和s值没有嵌入到层次结构中。DER编码的ASN.1整数值是有符号的,但如果设置了最高有效位,则数字将填充为零字节,因此结果始终为正。@K.Os我认为linehrr已经正确回答了这个问题。如果他的解决方案不起作用,请再打电话给我。