在Java中加载原始64字节长的ECDSA公钥 [英] Loading raw 64-byte long ECDSA public key in Java

查看:784
本文介绍了在Java中加载原始64字节长的ECDSA公钥的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个raw(r,s)格式的ECDSA NIST P-256公钥。似乎没有简单的方法将其加载到实现java.security.interfaces.ECPublicKey的对象中。

I have a raw (r,s) format ECDSA NIST P-256 public key. It seems that there is no simple way to load it into an object that implements java.security.interfaces.ECPublicKey.

什么是最简洁的方法来加载64字节的公共

What is the cleanest way to load a 64 byte public key so that it can be used to check signatures?

这个答案会很难,如果我们这样做使用<$

解决方案

private static byte[] P256_HEAD = Base64.getDecoder().decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE");

public static ECPublicKey convertP256Key(byte[] w) throws InvalidKeySpecException {
    byte[] encodedKey = new byte[P256_HEAD.length + w.length];
    System.arraycopy(P256_HEAD, 0, encodedKey, 0, P256_HEAD.length);
    System.arraycopy(w, 0, encodedKey, 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");
    }
    X509EncodedKeySpec ecpks = new X509EncodedKeySpec(encodedKey);
    return (ECPublicKey) eckf.generatePublic(ecpks);
}

用法:

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

我用头像生成头像:

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[] encoded = kp.getPublic().getEncoded();
    return Arrays.copyOf(encoded, encoded.length - 2 * (size / Byte.SIZE));
}

调用者:

String name = "NIST P-256";
int size = 256;
byte[] head = createHeadForNamedCurve(name, size);
System.out.println(Base64.getEncoder().encodeToString(head));

这个想法是创建一个X509编码的键, c $ c> w (在之前的字节包含命名曲线的OID的ASN.1 DER编码和以字节 04结尾的结构开销) code>表示未压缩点)。然后我们用 w 替换结尾处的随机点 w ,然后再次解码。

The idea behind this is to create an X509 encoded key, which happily ends with the public point w at the end (the bytes before that contain the ASN.1 DER encoding of the OID of the named curve and structural overhead, ending with byte 04 indicating an uncompressed point). Then we replace the "random" point w at the end with your w and we decode it again.

Java 7需要用于EC功能,Java 8用于Base 64编码器/解码器,没有额外的库和东西。请注意,在打印输出时,实际上会将公开密钥显示为命名的曲线,其他解决方案不会这样做。

Java 7 required for the EC functionality and Java 8 for the Base 64 encoder / decoder, no additional libraries and stuff. Note that this will actually display the public key as a named curve when printed out, something the other solutions won't do.

这篇关于在Java中加载原始64字节长的ECDSA公钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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