首页 > 解决方案 > 如何从 33 字节重构 33 字节压缩 NIST P-256 公钥?

问题描述

假设可以像这样创建 33 字节编码的公钥:

Security.addProvider(provider)
val generator = KeyPairGenerator.getInstance("ECDSA")
val ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1")
generator.initialize(ecSpec)
val keyPair = generator.generateKeyPair()
val privateKey = keyPair.private as ECPrivateKey
val publicKey = keyPair.public as ECPublicKey
val publicEncoded = publicKey.q.getEncoded(true)

我怎样才能在另一边再次重建它(当我只有从这里发送的 33 个字节时)?

我正在尝试以下代码:

val publicKey =KeyFactory.getInstance("EC").generatePublic(X509EncodedKeySpec(publicEncoded))

但我想这是完全错误的,因为我得到了:

java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: 错误:0c000079:ASN.1 编码例程:OPENSSL_internal:HEADER_TOO_LONG

我也在尝试:

val generator = KeyPairGenerator.getInstance("ECDSA")
val ecPublicKey = generator
        .generatePublic(X509EncodedKeySpec((publicEncoded))) as ECPublicKey

但错误是:

java.security.spec.InvalidKeySpecException:编码的密钥规范无法识别

如何实现我的目标?

标签: androidkotlincryptographybouncycastleecdsa

解决方案


主要问题是您publicEncoded的不是编码的公钥,而是编码的ECPoint( publicKey.q)。这意味着您需要首先重建点,然后提供适当的曲线来重建密钥以获得正确的ECPublicKeySpec.

  1. 首先用 重新获得选择的曲线规格ECNamedCurveTable.getParameterSpec("secp256r1")。然后您可以使用它ecSpec.curve.decodePoint(publicEncoded)来重建 BCECPoint实例。
  2. 将 BouncyCastleECNamedCurveParameterSpec转换为java.security.spec.ECParameterSpec并将 BouncyCastleECPoint转换为 java java.security.spec.ECPoint。然后构造适当的,然后密钥生成器ECPublicKeySpec可以使用它来重新创建完整的.ECDSAPublicKey

参考:


推荐阅读