在Java中加载原始的64字节长的ECDSA公钥

在Java中加载原始的64字节长的ECDSA公钥,第1张

在Java中加载原始的64字节长的ECDSA公钥

EC功能需要Java 7,而base 64编码器/解码器则需要Java8,没有其他库-仅是纯Java。请注意,打印出来时,这实际上会将公钥显示为已_命名的曲线_ ,而其他大多数解决方案都不会这样做。 如果您具有最新的运行时,则其他答案更为简洁。

如果我们使用进行此回答,将很难

ECPublicKeySpec
。因此,让我们作弊一下,
X509EnpredKeySpec
改用:

private static byte[] P256_HEAD = base64.getDeprer().depre("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE");public static ECPublicKey generateP256PublicKeyFromFlatW(byte[] w) throws InvalidKeySpecException {    byte[] enpredKey = new byte[P256_HEAD.length + w.length];    System.arraycopy(P256_HEAD, 0, enpredKey, 0, P256_HEAD.length);    System.arraycopy(w, 0, enpredKey, P256_HEAD.length, w.length);    KeyFactory eckf;    try {        eckf = KeyFactory.getInstance("EC");    } catch (NoSuchAlgorithmException e) {        throw new IllegalStateException("EC key factory not present in runtime");    }    X509EnpredKeySpec ecpks = new X509EnpredKeySpec(enpredKey);    return (ECPublicKey) eckf.generatePublic(ecpks);}

用法:

ECPublicKey key = generateP256PublicKeyFromFlatW(w);System.out.println(key);

其背后的想法是创建一个临时的X509编码密钥,该密钥愉快地以公共点

w
结尾。之前的字节包含命名曲线的OID的ASN.1
DER编码和结构开销,最后
04
一个字节指示未压缩的点。

删除未压缩点值的32字节X和Y值以创建标头。这仅适用于该点,因为该点是静态大小的-它在末端的位置仅由曲线的大小确定。

现在,该功能所需要做的

generateP256PublicKeyFromFlatW
就是将接收到的公共点添加
w
到标头,并通过为实现的解码器运行它
X509EnpredKeySpec


上面的代码使用了原始的,未压缩的公共EC点-仅有32个字节的X和Y-没有带value的未压缩点指示符

04
。当然,也很容易支持65个字节的压缩点:

public static ECPublicKey generateP256PublicKeyFromUncompressedW(byte[] w) throws InvalidKeySpecException {    if (w[0] != 0x04) {        throw new InvalidKeySpecException("w is not an uncompressed key");    }    return generateP256PublicKeyFromFlatW(Arrays.copyOfRange(w, 1, w.length));}

最终,我

P256_HEAD
使用以下方法在base 64中生成了恒定的头值:

private static byte[] createHeadForNamedCurve(String name, int size)        throws NoSuchAlgorithmException,        InvalidAlgorithmParameterException, IOException {    KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");    ECGenParameterSpec m = new ECGenParameterSpec(name);    kpg.initialize(m);    KeyPair kp = kpg.generateKeyPair();    byte[] enpred = kp.getPublic().getEnpred();    return Arrays.copyOf(enpred, enpred.length - 2 * (size / Byte.SIZE));}

致电者:

String name = "NIST P-256";int size = 256;byte[] head = createHeadForNamedCurve(name, size);System.out.println(base64.getEnprer().enpreToString(head));


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5177669.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-18
下一篇 2022-11-18

发表评论

登录后才能评论

评论列表(0条)

保存