当前位置: 首页 > 知识库问答 >
问题:

如何从33字节重构33字节压缩的NIST P-256公钥?

鲁龙野
2023-03-14

假设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: error: 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:无法识别编码的密钥规范

如何实现我的目标?

共有2个答案

韩宏朗
2023-03-14

这应该可以完成工作:

import org.bouncycastle.jce.ECNamedCurveTable
import org.bouncycastle.jce.spec.ECPublicKeySpec

fun publicKeyFromCompressed(compressedPublicKey: ByteArray): PublicKey {
    val ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1")
    val point = ecSpec.curve.decodePoint(compressedPublicKey)
    val publicKeySpec = ECPublicKeySpec(point, ecSpec)
    val keyFactory = KeyFactory.getInstance("ECDSA")
    val publicKey = keyFactory.generatePublic(publicKeySpec)
    return publicKey
}
郁明诚
2023-03-14

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

  1. 首先使用ECNamedCurveTable.getParameterSpec(“secp256r1”)重新获取所选曲线规范。然后,您可以使用 ecSpec.curve.decodePoint(publicEncoded) 来重建 BC ECPoint 实例。
  2. 将 BouncyCastle ECNamedCurveParameterSpec 转换为 java.security.spec.ECParameterSpec,将 BouncyCastle ECPoint 转换为 java java.security.spec.ECPoint。然后构建相应的 ECPublicKeySpec,然后 ECDSA 密钥生成器可以使用它来重新创建完整的公钥

参考资料:

  • ECPoint。getEncoded()/ECCurve。解码点(字节[])
  • ECNamedCurveParameterSpec/ECPublicKeySpec
  • ECPublicKeySpec(ECPoint,ECParameterSpec)
 类似资料:
  • 我需要生成这样的公钥,并对字节进行额外的签名(这将包括之前生成的密钥) 我需要构造以下字节:ASN.1 前缀签名(33 字节压缩 NIST P-256 公钥) 签名应从其他定义的私钥传递 ECDSA规范: ● 曲线: NIST P-256也称为secp256r1和prime256v1(openssl) ●签名格式ASN.1。ECDSA签名的r和s值必须是正整数,并且DER编码为正整数。 Andro

  • 问题内容: 情况如下: 我从Amazon S3获取gzip压缩的xml文档 我以文件形式阅读它们 题 如何直接解压缩流并读取内容? 我不想创建临时文件,它们看起来不太好。 问题答案: 是的,您可以使用该模块解压缩字节流: 到标头的32个偏移量表示gzip标头是预期的但已跳过。 S3键对象是一个迭代器,因此您可以执行以下操作:

  • 说明 IntelliJ IDEA 有很多人性化的设置我们必须单独拿出来讲解,也因为这些人性化的设置让我们这些 IntelliJ IDEA 死忠粉更加死心塌地使用它和分享它。 常用设置 如上图 Gif 所示,当我们设置了组件窗口的 Pinned Mode 属性之后,在切换到其他组件窗口的时候,已设置该属性的窗口不会自动隐藏。 如上图 Gif 所示,我们可以对某些文件进行添加到收藏夹,然后在收藏夹组件

  • 问题内容: 在服务器(C ++)上,二进制数据使用以下函数压缩: 并将其发送到客户端(Java)。在客户端(Java)上,应使用以下代码段对数据进行解压缩: 问题是,当它尝试读入while循环时,它总是抛出: java.util.zip.ZipException:无效的存储块长度 在检查其他可能原因之前,有人可以告诉我是否可以使用compress2在一侧进行压缩,并在另一侧使用上述代码将其解压缩,

  • 问题内容: 我正在尝试编写一个可以压缩数据的类。以下代码失败(不会引发异常,但目标.gz文件为空。) 此外:我不想像在所有示例中一样直接生成.gz文件。我只想获取压缩的数据,以便在将数据写入文件之前将其加密。 如果我直接写入文件,则一切正常: 但是,如果我想将其“旁路”到字节数组流,则不会产生单个字节- 始终为空。 问题答案: 问题是您没有关闭。在关闭它之前,输出将是不完整的。 您只需要 在 读取

  • 在服务器(C)上,使用ZLib函数压缩二进制数据: 它被发送到客户端(Java)。在客户端(Java),应使用以下代码段解压缩数据: 问题是,当它尝试读取时,它总是抛出: java.util.zip。ZipException:存储的块长度无效 在我检查其他可能的原因之前,有人能告诉我我可以用压缩器2在一侧压缩并使用上述代码在另一侧解压缩它,这样我就可以消除这个问题了吗?此外,如果有人对这里可能出现