在 Java 中加载原始的 64 字节长 ECDSA public 密钥
Loading raw 64-byte long ECDSA public key in Java
我有一个原始 (r,s) 格式的 ECDSA NIST P-256 public 密钥。似乎没有简单的方法可以将其加载到实现 java.security.interfaces.ECPublicKey.
的对象中
加载 64 字节 public 密钥以用于检查签名的最简洁方法是什么?
Java 确实让密码学变得很啰嗦。
从给定的 EC 点创建 public 密钥的过程:
- 根据给定的坐标构造一个
ECPoint
对象。
- 根据曲线的信息构造一个
ECParameterSpec
对象。
- 从您的
ECPoint
和 ECParameterSpec
对象构造一个 ECPublicKeySpec
对象。
- 使用您的
ECPublicKeySpec
对象调用 KeyFactory.generatePublic()
以检索 PublicKey
对象。
- 根据需要将
PublicKey
转换为 ECPublicKey
。
示例如下:
// Setup for P-256 curve params
BigInteger p256_p = new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16);
BigInteger p256_a = new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16);
BigInteger p256_b = new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16);
byte[] p256_seed = {
(byte) 0xc4, (byte) 0x9d, (byte) 0x36, (byte) 0x08,
(byte) 0x86, (byte) 0xe7, (byte) 0x04, (byte) 0x93,
(byte) 0x6a, (byte) 0x66, (byte) 0x78, (byte) 0xe1,
(byte) 0x13, (byte) 0x9d, (byte) 0x26, (byte) 0xb7,
(byte) 0x81, (byte) 0x9f, (byte) 0x7e, (byte) 0x90
};
BigInteger p256_xg = new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16);
BigInteger p256_yg = new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16);
BigInteger p256_n = new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16);
// Construct prime field
ECFieldFp p256_field = new ECFieldFp(p256_p);
// Construct curve from parameters
EllipticCurve p256 = new EllipticCurve(p256_field, p256_a, p256_b, p256_seed);
// Construct base point for curve
ECPoint p256_base = new ECPoint(p256_xg, p256_yg);
// Construct curve parameter specifications object
ECParameterSpec p256spec = new ECParameterSpec(p256, p256_base, p256_n, 1); // Co-factor 1 for prime curves
// ------------------------------------------------------------- //
// Construct EC point from "raw" public key
ECPoint point = new ECPoint(r, s); // r, s is of type BigInteger
// Create a EC public key specification object from point and curve
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, p256spec);
// Retrieve EC KeyFactory
KeyFactory ECFactory = KeyFactory.getInstance("EC");
// Generate public key via KeyFactory
PublicKey pubKey = ECFactory.generatePublic(pubKeySpec);
ECPublicKey ECPubKey = (ECPublicKey) pubKey;
出于性能原因,生成一次 ECParameterSpec(可能在静态初始化程序块中)可能会有所帮助。
注意:可能有更简单的方法来生成 ECParameterSpec 对象(例如通过命名曲线),但到目前为止我只发现 ECGenParameterSpec
具有此功能。如果有更轻松的方法,请在评论中告诉我。
为了省去执行上述操作的痛苦,请在 X.509 下对您的 EC 密钥进行编码,这将完整描述密钥 并且 使加载变得更加容易。
在java中,使用ECPublicKey,您需要做的就是将ECPublicKey.getEncoded()
和pass/save字节数组调用到下一个需要密钥的位置。然后可以通过以下方式重建 X.509 编码密钥:
// Retrieve EC KeyFactory
KeyFactory ECFactory = KeyFactory.getInstance("EC");
// Generate public key via KeyFactory
PublicKey pubKey = ECFactory.generatePublic(new X509EncodedKeySpec(data));
ECPublicKey ECPubKey = (ECPublicKey) pubKey;
其中 "data" 是编码后的字节数组。
EC Public 键是一个由 x 和 y 坐标组成的点。我写了一次下面的代码段来将 EC x, y 指向 publicKey
对象。希望这会帮助你。
供您参考:
rawPubKey = 04 + x co-ordinate + y co-ordinate (Hex String)
curveName = P-256 (String)
示例 EC Public P-256 的要点:
rawPubKey = 04 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296 4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5
BC 提供商: 您需要 Bouncy Castle 提供商。我用的是bcprov-jdk15on-149.jar,不过你可以从here.
下载最新版本
/**
* This method converts the uncompressed raw EC public key into java.security.interfaces.ECPublicKey
* @param rawPubKey
* @param curveName
* @return java.security.interfaces.ECPublicKey
*/
public ECPublicKey ucPublicKeyToPublicKey(String rawPubKey, String curveName) {
byte[] rawPublicKey = Helper.toByte(rawPubKey);
ECPublicKey ecPublicKey = null;
KeyFactory kf = null;
ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec(curveName);
ECCurve curve = ecNamedCurveParameterSpec.getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecNamedCurveParameterSpec.getSeed());
java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, rawPublicKey);
ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve, ecNamedCurveParameterSpec);
java.security.spec.ECPublicKeySpec publicKeySpec = new java.security.spec.ECPublicKeySpec(ecPoint, ecParameterSpec);
kf = java.security.KeyFactory.getInstance("EC");
try {
ecPublicKey = (ECPublicKey) kf.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Caught Exception public key: " + e.toString());
}
return ecPublicKey;
}
编辑:
这是toByte()
方法:
public static byte[] toByte(String hex) {
if (hex == null)
return null;
hex = hex.replaceAll("\s", "");
byte[] buffer = null;
if (hex.length() % 2 != 0) {
hex = "0" + hex;
}
int len = hex.length() / 2;
buffer = new byte[len];
for (int i = 0; i < len; i++) {
buffer[i] = (byte) Integer.parseInt(
hex.substring(i * 2, i * 2 + 2), 16);
}
return buffer;
}
但您可以使用自己的实现。这是另一个:
import javax.xml.bind.DatatypeConverter;
public static byte[] toByte(String hex) {{
return DatatypeConverter.parseHexBinary(hex);
}
Java EC 功能需要 7,Base 64 编码器/解码器需要 Java 8,没有额外的库 - 只是简单的 Java。请注意,这实际上会在打印时将 public 键显示为 命名曲线 ,这是大多数其他解决方案无法做到的。 如果你有up-to-date运行时间,this other answer更干净。
如果我们使用 ECPublicKeySpec
,这个答案将很难回答。所以让我们作弊并使用 X509EncodedKeySpec
代替:
private static byte[] P256_HEAD = Base64.getDecoder().decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE");
/**
* Converts an uncompressed secp256r1 / P-256 public point to the EC public key it is representing.
* @param w a 64 byte uncompressed EC point consisting of just a 256-bit X and Y
* @return an <code>ECPublicKey</code> that the point represents
*/
public static ECPublicKey generateP256PublicKeyFromFlatW(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 = generateP256PublicKeyFromFlatW(w);
System.out.println(key);
这背后的想法是创建一个临时的 X509 编码密钥,它愉快地以 public 点 w
最后结束。之前的字节包含命名曲线的 OID 和结构开销的 ASN.1 DER 编码,以字节 04
结尾,指示未压缩点。 Here is an example 结构是什么样的,对 32 字节的 X 和 Y 使用值 1 和 2。
删除未压缩点值的 32 字节 X 和 Y 值以创建 header。这只有效,因为该点是静态大小的 - 它在末端的位置仅由曲线的大小决定。
现在函数generateP256PublicKeyFromFlatW
中所需要的就是通过为 X509EncodedKeySpec
.
实现的解码器
以上代码使用原始的、未压缩的 public EC 点——只有 32 字节的 X 和 Y——没有值为 04
的未压缩点指示符。当然支持65字节压缩点也很容易:
/**
* Converts an uncompressed secp256r1 / P-256 public point to the EC public key it is representing.
* @param w a 64 byte uncompressed EC point starting with <code>04</code>
* @return an <code>ECPublicKey</code> that the point represents
*/
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));
}
最后,我使用 base 64 生成了常量 P256_HEAD
head 值:
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));
在 Bouncycastle 的帮助下,这对我有用:
ECParameterSpec ecParameterSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
ECNamedCurveSpec params = new ECNamedCurveSpec("secp256r1", spec.getCurve(), spec.getG(), spec.getN());
ECPoint publicPoint = ECPointUtil.decodePoint(params.getCurve(), publicKeyByteArray);
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(publicPoint, params);
PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
What is the cleanest way to load a 64 byte public key so that it can be used to check signatures?
我能召集的最干净的!应该也适用于其他曲线..
注意:仅限于 SunJCE 提供者或 Android API 26+(可能有更多具有此功能的提供者,我目前还不知道它们。
public static ECPublicKey rawToEncodedECPublicKey(String curveName, byte[] rawBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidParameterSpecException {
KeyFactory kf = KeyFactory.getInstance("EC");
byte[] x = Arrays.copyOfRange(rawBytes, 0, rawBytes.length/2);
byte[] y = Arrays.copyOfRange(rawBytes, rawBytes.length/2, rawBytes.length);
ECPoint w = new ECPoint(new BigInteger(1,x), new BigInteger(1,y));
return (ECPublicKey) kf.generatePublic(new ECPublicKeySpec(w, ecParameterSpecForCurve(curveName)));
}
public static ECParameterSpec ecParameterSpecForCurve(String curveName) throws NoSuchAlgorithmException, InvalidParameterSpecException {
AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
params.init(new ECGenParameterSpec(curveName));
return params.getParameterSpec(ECParameterSpec.class);
}
我有一个原始 (r,s) 格式的 ECDSA NIST P-256 public 密钥。似乎没有简单的方法可以将其加载到实现 java.security.interfaces.ECPublicKey.
的对象中加载 64 字节 public 密钥以用于检查签名的最简洁方法是什么?
Java 确实让密码学变得很啰嗦。
从给定的 EC 点创建 public 密钥的过程:
- 根据给定的坐标构造一个
ECPoint
对象。 - 根据曲线的信息构造一个
ECParameterSpec
对象。 - 从您的
ECPoint
和ECParameterSpec
对象构造一个ECPublicKeySpec
对象。 - 使用您的
ECPublicKeySpec
对象调用KeyFactory.generatePublic()
以检索PublicKey
对象。 - 根据需要将
PublicKey
转换为ECPublicKey
。
示例如下:
// Setup for P-256 curve params
BigInteger p256_p = new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16);
BigInteger p256_a = new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16);
BigInteger p256_b = new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16);
byte[] p256_seed = {
(byte) 0xc4, (byte) 0x9d, (byte) 0x36, (byte) 0x08,
(byte) 0x86, (byte) 0xe7, (byte) 0x04, (byte) 0x93,
(byte) 0x6a, (byte) 0x66, (byte) 0x78, (byte) 0xe1,
(byte) 0x13, (byte) 0x9d, (byte) 0x26, (byte) 0xb7,
(byte) 0x81, (byte) 0x9f, (byte) 0x7e, (byte) 0x90
};
BigInteger p256_xg = new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16);
BigInteger p256_yg = new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16);
BigInteger p256_n = new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16);
// Construct prime field
ECFieldFp p256_field = new ECFieldFp(p256_p);
// Construct curve from parameters
EllipticCurve p256 = new EllipticCurve(p256_field, p256_a, p256_b, p256_seed);
// Construct base point for curve
ECPoint p256_base = new ECPoint(p256_xg, p256_yg);
// Construct curve parameter specifications object
ECParameterSpec p256spec = new ECParameterSpec(p256, p256_base, p256_n, 1); // Co-factor 1 for prime curves
// ------------------------------------------------------------- //
// Construct EC point from "raw" public key
ECPoint point = new ECPoint(r, s); // r, s is of type BigInteger
// Create a EC public key specification object from point and curve
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, p256spec);
// Retrieve EC KeyFactory
KeyFactory ECFactory = KeyFactory.getInstance("EC");
// Generate public key via KeyFactory
PublicKey pubKey = ECFactory.generatePublic(pubKeySpec);
ECPublicKey ECPubKey = (ECPublicKey) pubKey;
出于性能原因,生成一次 ECParameterSpec(可能在静态初始化程序块中)可能会有所帮助。
注意:可能有更简单的方法来生成 ECParameterSpec 对象(例如通过命名曲线),但到目前为止我只发现 ECGenParameterSpec
具有此功能。如果有更轻松的方法,请在评论中告诉我。
为了省去执行上述操作的痛苦,请在 X.509 下对您的 EC 密钥进行编码,这将完整描述密钥 并且 使加载变得更加容易。
在java中,使用ECPublicKey,您需要做的就是将ECPublicKey.getEncoded()
和pass/save字节数组调用到下一个需要密钥的位置。然后可以通过以下方式重建 X.509 编码密钥:
// Retrieve EC KeyFactory
KeyFactory ECFactory = KeyFactory.getInstance("EC");
// Generate public key via KeyFactory
PublicKey pubKey = ECFactory.generatePublic(new X509EncodedKeySpec(data));
ECPublicKey ECPubKey = (ECPublicKey) pubKey;
其中 "data" 是编码后的字节数组。
EC Public 键是一个由 x 和 y 坐标组成的点。我写了一次下面的代码段来将 EC x, y 指向 publicKey
对象。希望这会帮助你。
供您参考:
rawPubKey = 04 + x co-ordinate + y co-ordinate (Hex String)
curveName = P-256 (String)
示例 EC Public P-256 的要点:
rawPubKey = 04 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296 4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5
BC 提供商: 您需要 Bouncy Castle 提供商。我用的是bcprov-jdk15on-149.jar,不过你可以从here.
下载最新版本/**
* This method converts the uncompressed raw EC public key into java.security.interfaces.ECPublicKey
* @param rawPubKey
* @param curveName
* @return java.security.interfaces.ECPublicKey
*/
public ECPublicKey ucPublicKeyToPublicKey(String rawPubKey, String curveName) {
byte[] rawPublicKey = Helper.toByte(rawPubKey);
ECPublicKey ecPublicKey = null;
KeyFactory kf = null;
ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec(curveName);
ECCurve curve = ecNamedCurveParameterSpec.getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecNamedCurveParameterSpec.getSeed());
java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, rawPublicKey);
ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve, ecNamedCurveParameterSpec);
java.security.spec.ECPublicKeySpec publicKeySpec = new java.security.spec.ECPublicKeySpec(ecPoint, ecParameterSpec);
kf = java.security.KeyFactory.getInstance("EC");
try {
ecPublicKey = (ECPublicKey) kf.generatePublic(publicKeySpec);
} catch (Exception e) {
System.out.println("Caught Exception public key: " + e.toString());
}
return ecPublicKey;
}
编辑:
这是toByte()
方法:
public static byte[] toByte(String hex) {
if (hex == null)
return null;
hex = hex.replaceAll("\s", "");
byte[] buffer = null;
if (hex.length() % 2 != 0) {
hex = "0" + hex;
}
int len = hex.length() / 2;
buffer = new byte[len];
for (int i = 0; i < len; i++) {
buffer[i] = (byte) Integer.parseInt(
hex.substring(i * 2, i * 2 + 2), 16);
}
return buffer;
}
但您可以使用自己的实现。这是另一个:
import javax.xml.bind.DatatypeConverter;
public static byte[] toByte(String hex) {{
return DatatypeConverter.parseHexBinary(hex);
}
Java EC 功能需要 7,Base 64 编码器/解码器需要 Java 8,没有额外的库 - 只是简单的 Java。请注意,这实际上会在打印时将 public 键显示为 命名曲线 ,这是大多数其他解决方案无法做到的。 如果你有up-to-date运行时间,this other answer更干净。
如果我们使用 ECPublicKeySpec
,这个答案将很难回答。所以让我们作弊并使用 X509EncodedKeySpec
代替:
private static byte[] P256_HEAD = Base64.getDecoder().decode("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE");
/**
* Converts an uncompressed secp256r1 / P-256 public point to the EC public key it is representing.
* @param w a 64 byte uncompressed EC point consisting of just a 256-bit X and Y
* @return an <code>ECPublicKey</code> that the point represents
*/
public static ECPublicKey generateP256PublicKeyFromFlatW(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 = generateP256PublicKeyFromFlatW(w);
System.out.println(key);
这背后的想法是创建一个临时的 X509 编码密钥,它愉快地以 public 点 w
最后结束。之前的字节包含命名曲线的 OID 和结构开销的 ASN.1 DER 编码,以字节 04
结尾,指示未压缩点。 Here is an example 结构是什么样的,对 32 字节的 X 和 Y 使用值 1 和 2。
删除未压缩点值的 32 字节 X 和 Y 值以创建 header。这只有效,因为该点是静态大小的 - 它在末端的位置仅由曲线的大小决定。
现在函数generateP256PublicKeyFromFlatW
中所需要的就是通过为 X509EncodedKeySpec
.
以上代码使用原始的、未压缩的 public EC 点——只有 32 字节的 X 和 Y——没有值为 04
的未压缩点指示符。当然支持65字节压缩点也很容易:
/**
* Converts an uncompressed secp256r1 / P-256 public point to the EC public key it is representing.
* @param w a 64 byte uncompressed EC point starting with <code>04</code>
* @return an <code>ECPublicKey</code> that the point represents
*/
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));
}
最后,我使用 base 64 生成了常量 P256_HEAD
head 值:
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));
在 Bouncycastle 的帮助下,这对我有用:
ECParameterSpec ecParameterSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
ECNamedCurveSpec params = new ECNamedCurveSpec("secp256r1", spec.getCurve(), spec.getG(), spec.getN());
ECPoint publicPoint = ECPointUtil.decodePoint(params.getCurve(), publicKeyByteArray);
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(publicPoint, params);
PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
What is the cleanest way to load a 64 byte public key so that it can be used to check signatures?
我能召集的最干净的!应该也适用于其他曲线..
注意:仅限于 SunJCE 提供者或 Android API 26+(可能有更多具有此功能的提供者,我目前还不知道它们。
public static ECPublicKey rawToEncodedECPublicKey(String curveName, byte[] rawBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidParameterSpecException {
KeyFactory kf = KeyFactory.getInstance("EC");
byte[] x = Arrays.copyOfRange(rawBytes, 0, rawBytes.length/2);
byte[] y = Arrays.copyOfRange(rawBytes, rawBytes.length/2, rawBytes.length);
ECPoint w = new ECPoint(new BigInteger(1,x), new BigInteger(1,y));
return (ECPublicKey) kf.generatePublic(new ECPublicKeySpec(w, ecParameterSpecForCurve(curveName)));
}
public static ECParameterSpec ecParameterSpecForCurve(String curveName) throws NoSuchAlgorithmException, InvalidParameterSpecException {
AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
params.init(new ECGenParameterSpec(curveName));
return params.getParameterSpec(ECParameterSpec.class);
}