我可以从openssh公钥和ECParameterSpec的Q值创建JCE ECPublicKey吗? [英] Can I create a JCE ECPublicKey from a Q value from an openssh public key and ECParameterSpec

查看:295
本文介绍了我可以从openssh公钥和ECParameterSpec的Q值创建JCE ECPublicKey吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读openssh格式的椭圆曲线公共密钥( RFC 5656第3.1节,),并希望使用JCE从BigInteger Q值获取到ECPublicKey实例(而不是说BouncyCastle).我要执行此操作以验证 JWT 签名.

I'm reading openssh format elliptic curve public keys (RFC 5656, section 3.1) and would like to get from a BigInteger Q value to an ECPublicKey instance using JCE (rather than say BouncyCastle). I want to do this to verify JWT signatures.

例如 https://api.github.com/users/davidcarboni/keys :

ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK8hPtB72/sfYgNw1WTska2DNOJFx+QhUxuV6OLINSD2ty+6gxcM8yZrvMqWdMePGRb2cGh8L/0bGOk+64IQ/pM=

看起来我可以使用ECPublicKeySpec.这需要两个参数. ECPointECParameterSpec.我可以使用以下JCE代码(以及密钥数据中的openssh标识符,例如"nistp256")来获取参数规范:

It looks like I can use ECPublicKeySpec. This takes two parameters. An ECPoint and an ECParameterSpec. I'm able to get the parameter spec using the following JCE code (and the openssh identifier from the key data, say "nistp256"):

ECParameterSpec getECParameterSpec(String identifier) {
    try {
        AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
        String name = identifier.replace("nist", "sec") + "r1";
        parameters.init(new ECGenParameterSpec(name));
        return parameters.getParameterSpec(ECParameterSpec.class);
    } catch (InvalidParameterSpecException | NoSuchAlgorithmException e) {
        throw new IllegalArgumentException("Unable to get parameter spec for identifier " + identifier, e);
    }
}

我已经成功地从关键数据中解析了Q值. RFC 5656告诉我"Q是从椭圆曲线点编码为八位字节串的公共密钥"),但是JCE的ECPoint类的构造函数采用两个参数X和Y.

I've successfully parsed the Q value from the key data. RFC 5656 tells me that "Q is the public key encoded from an elliptic curve point into an octet string") however the constructor of JCE's ECPoint class takes two parameters, X and Y.

我可以从Q转到X和Y,还是需要采用其他方法?

Can I get to X and Y from Q, or do I need to take a different approach?

(请注意,我完全无权使用私钥)

(NB I quite rightly don't have access to the private key)

推荐答案

您输入的base64部分具有等价的

The base64 portion of your input has the equivalent hex of

00 00 00 13 65 63 64 73 61 2D 73 68 61 32 2D 6E 
69 73 74 70 32 35 36 00 00 00 08 6E 69 73 74 70 
32 35 36 00 00 00 41 04 AF 21 3E D0 7B DB FB 1F 
62 03 70 D5 64 EC 91 AD 83 34 E2 45 C7 E4 21 53 
1B 95 E8 E2 C8 35 20 F6 B7 2F BA 83 17 0C F3 26 
6B BC CA 96 74 C7 8F 19 16 F6 70 68 7C 2F FD 1B 
18 E9 3E EB 82 10 FE 93 

65 63 64以"ecd"的身份跳到我身上(肯定是"ecdsa-sha2-nistp256").

65 63 64 jumped out to me as "ecd" (sure enough, "ecdsa-sha2-nistp256").

所以斑点看起来是

  • 字符串/有效载荷的大尾数长度(19)
  • 字符串"ecdsa-sha2-nistp256"
  • 字符串/有效载荷的大尾数长度(8)
  • 字符串"nistp256"
  • 有效载荷的大尾数长度(0x41 == 65)
  • 编码的ECPoint Q(04 AF 21 ... 10 FE 93)
  • Big Endian length of a string/payload (19)
  • The string "ecdsa-sha2-nistp256"
  • Big Endian length of a string/payload (8)
  • The string "nistp256"
  • Big Endian length of a payload (0x41 == 65)
  • The encoded ECPoint Q (04 AF 21 ... 10 FE 93)

编码的ECPoint以04开头,指示它是未压缩的点(最常见的编码). 04编码规则(来自 http://www.secg.org/sec1-v2. pdf ,第2.3.5节,第3步)说,剩余有效载荷是X和Y,每个有效载荷都用零填充到曲线字段的编码大小.

The encoded ECPoint starts with 04 indicating it is an uncompressed point (the most common encoding). The 04 encoding rules (from http://www.secg.org/sec1-v2.pdf, 2.3.5, step 3) say that the remaining payload is X and Y, each left-padded with zeros to the encoding size of the curve field.

所以您的ECPoint看起来像

So your ECPoint looks like

04
Qx:
AF 21 3E D0 7B DB FB 1F 62 03 70 D5 64 EC 91 AD
83 34 E2 45 C7 E4 21 53 1B 95 E8 E2 C8 35 20 F6
Qy:
B7 2F BA 83 17 0C F3 26 6B BC CA 96 74 C7 8F 19
16 F6 70 68 7C 2F FD 1B 18 E9 3E EB 82 10 FE 93

在C#中,您需要a)反转Qx和Qy的每个字节(因为.NET BigInteger期望使用Little Endian,而这些是Big Endian),并且b)将填充0x00字节的重要性大于0xAF和0xB7字节,因为它们设置了高位(将被解释为负数).不知道Java是否有这些古怪之处.

In C# you'd need to a) reverse the bytes of each of Qx and Qy (because the .NET BigInteger expects Little Endian, and these are Big Endian) and b) put a padding 0x00 byte as more significant than the 0xAF and 0xB7 bytes, since they have their high bits set (and would be interpreted as negative numbers). Don't know if Java has either of those quirks.

这篇关于我可以从openssh公钥和ECParameterSpec的Q值创建JCE ECPublicKey吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆