android - 如何从 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:编码的密钥规范无法识别
如何实现我的目标?
解决方案
主要问题是您publicEncoded
的不是编码的公钥,而是编码的ECPoint
( publicKey.q
)。这意味着您需要首先重建点,然后提供适当的曲线来重建密钥以获得正确的ECPublicKeySpec
.
- 首先用 重新获得选择的曲线规格
ECNamedCurveTable.getParameterSpec("secp256r1")
。然后您可以使用它ecSpec.curve.decodePoint(publicEncoded)
来重建 BCECPoint
实例。 - 将 BouncyCastle
ECNamedCurveParameterSpec
转换为java.security.spec.ECParameterSpec
并将 BouncyCastleECPoint
转换为 javajava.security.spec.ECPoint
。然后构造适当的,然后密钥生成器ECPublicKeySpec
可以使用它来重新创建完整的.ECDSA
PublicKey
参考:
推荐阅读
- php - 通过 cURL 和解析/输出响应获取“card-title”html 元素
- azure-cognitive-search - How to get the URL query string from Azure Search Parameters
- c++ - 当 ios::sync_with_stdio(0) 和 cin.tie(0) 在循环内写入时奇怪行为的解释
- javascript - 在对象上传播不可迭代实例的无效尝试
- r - Abbreviate Long Table with Kable/kableExtra?
- c++ - 如何使用二维数组创建游戏地图?
- c - fpic 和 O3 优化标志
- c++ - 使用地图
而不是矢量 避免指针失效 - c++ - Is it safe to cast between a function pointer and a member function pointer?
- jquery - How to create nested elements with classes inside li using jQuery