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));
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)