【问题标题】:How to decompress X9.62 coordinate如何解压X9.62坐标
【发布时间】:2020-11-16 17:30:33
【问题描述】:

我正在向我的方法传递一个 byte[],并且我正在尝试生成一个 pubKey。看错误看起来好像我首先需要在生成 pubKey 之前解压缩。

如何解码压缩坐标?

private static PublicKey getPublicKeyFromBytes(byte[] pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException 
{
       
        ECPoint point = new ECPoint(new BigInteger(pubKey), BigInteger.ZERO);
        ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
        KeyFactory kf = KeyFactory.getInstance("ECDSA", new BouncyCastleProvider());
        ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());
        ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
        ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec);
        return pk;
}

错误信息:

Exception in thread "main" java.security.spec.InvalidKeySpecException: invalid KeySpec: x value invalid for SecP256R1FieldElement
    at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(Unknown Source)

【问题讨论】:

  • 处理方式取决于指定点是压缩的还是未压缩的,请参阅here。例如,如果指定为未压缩,则前导字节为 04,接下来的 32 个字节是 x 坐标,接下来的 32 个字节是 y 坐标(对于 prime256v1)。对于 x 和 y 无符号 BigIntegers 将被创建 (new BigInteger(1, ...)) 和 ECPoint
  • 如果您可以包含您正在尝试读取的公钥,那么帮助您会更容易。只需包含Base64.getEncoder().encodeToString(pubKey) 的输出即可。
  • 在我的机器上,getPublicKeyFromBytes() 触发未压缩和压缩 X9.62 密钥的已发布错误,即从错误无法断定您的数据代表未压缩或压缩密钥(甚至是另一种格式)。相比之下,loadPubKey() 既适用于未压缩的 X9.62 密钥,也适用于压缩的 X9.62 密钥。由于您的数据使用后一种方法会触发错误,因此您的数据可能与 X9.62 格式不匹配。也许它是一个 X.509 密钥。如果你不想发布密钥,你可以检查这个,例如lapo.it/asn1js.

标签: java cryptography elliptic-curve


【解决方案1】:

如果您的pubKey 是X9.62 压缩或未压缩点,您可以在ECCurve 上使用decodePoint() 方法:

ECPoint point = spec.getCurve().decodePoint(pubKey);

【讨论】:

  • 当我使用 curve.decodePoint(pubKey) 我得到无效点 in thread "main" java.lang.IllegalArgumentException: Invalid point encoding 0x-58 at org.bouncycastle.math.ec.ECCurve.decodePoint(Unknown Source)
  • public static PublicKey loadPubKey(byte[] encodedPublicKey) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException { KeyFactory kf = KeyFactory.getInstance("ECDH", new BouncyCastleProvider()); ECParameterSpec parameterSpec = ECNamedCurveTable.getParameterSpec("prime256v1"); ECCurve curve = parameterSpec.getCurve(); ECPoint point = curve.decodePoint(encodedPublicKey); ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, parameterSpec); return kf.generatePublic(pubSpec); }
  • @user2748161 :根据错误消息,您的编码点以 0xA8 (-0x58) 开头。这与我能想到的任何格式都不匹配。在这一点上,除非您发布密钥(尽管您在发布 public 密钥时应该没有问题,但请随意将中间的内容留空)或在至少让我们知道数据的确切来源。
猜你喜欢
  • 2015-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
相关资源
最近更新 更多