|
|
@@ -11,7 +11,11 @@ import org.bouncycastle.crypto.params.ECDomainParameters;
|
|
|
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
|
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
|
|
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
|
|
|
+import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;
|
|
|
+import org.bouncycastle.jcajce.spec.OpenSSHPublicKeySpec;
|
|
|
import org.bouncycastle.math.ec.ECCurve;
|
|
|
+import org.bouncycastle.math.ec.ECPoint;
|
|
|
+import org.bouncycastle.math.ec.FixedPointCombMultiplier;
|
|
|
import org.bouncycastle.util.BigIntegers;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
@@ -20,6 +24,7 @@ import java.security.InvalidKeyException;
|
|
|
import java.security.Key;
|
|
|
import java.security.PrivateKey;
|
|
|
import java.security.PublicKey;
|
|
|
+import java.security.spec.KeySpec;
|
|
|
|
|
|
/**
|
|
|
* EC密钥参数相关工具类封装
|
|
|
@@ -45,7 +50,21 @@ public class ECKeyUtil {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 根据私钥参数获取公钥参数
|
|
|
+ *
|
|
|
+ * @param privateKeyParameters 私钥参数
|
|
|
+ * @return 公钥参数
|
|
|
+ * @since 5.5.9
|
|
|
+ */
|
|
|
+ public static ECPublicKeyParameters getPublicParams(ECPrivateKeyParameters privateKeyParameters) {
|
|
|
+ final ECDomainParameters domainParameters = privateKeyParameters.getParameters();
|
|
|
+ final ECPoint q = new FixedPointCombMultiplier().multiply(domainParameters.getG(), privateKeyParameters.getD());
|
|
|
+ return new ECPublicKeyParameters(q, domainParameters);
|
|
|
+ }
|
|
|
+
|
|
|
//--------------------------------------------------------------------------- Public Key
|
|
|
+
|
|
|
/**
|
|
|
* 转换为 ECPublicKeyParameters
|
|
|
*
|
|
|
@@ -91,8 +110,8 @@ public class ECKeyUtil {
|
|
|
/**
|
|
|
* 转换为ECPublicKeyParameters
|
|
|
*
|
|
|
- * @param x 公钥X
|
|
|
- * @param y 公钥Y
|
|
|
+ * @param x 公钥X
|
|
|
+ * @param y 公钥Y
|
|
|
* @param domainParameters ECDomainParameters
|
|
|
* @return ECPublicKeyParameters,x或y为{@code null}则返回{@code null}
|
|
|
*/
|
|
|
@@ -109,7 +128,7 @@ public class ECKeyUtil {
|
|
|
* @return ECPublicKeyParameters
|
|
|
*/
|
|
|
public static ECPublicKeyParameters toPublicParams(byte[] xBytes, byte[] yBytes, ECDomainParameters domainParameters) {
|
|
|
- if(null == xBytes || null == yBytes){
|
|
|
+ if (null == xBytes || null == yBytes) {
|
|
|
return null;
|
|
|
}
|
|
|
return toPublicParams(BigIntegers.fromUnsignedByteArray(xBytes), BigIntegers.fromUnsignedByteArray(yBytes), domainParameters);
|
|
|
@@ -187,6 +206,7 @@ public class ECKeyUtil {
|
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------- Private Key
|
|
|
+
|
|
|
/**
|
|
|
* 转换为 ECPrivateKeyParameters
|
|
|
*
|
|
|
@@ -220,7 +240,7 @@ public class ECKeyUtil {
|
|
|
/**
|
|
|
* 转换为 ECPrivateKeyParameters
|
|
|
*
|
|
|
- * @param d 私钥d值16进制字符串
|
|
|
+ * @param d 私钥d值16进制字符串
|
|
|
* @param domainParameters ECDomainParameters
|
|
|
* @return ECPrivateKeyParameters
|
|
|
*/
|
|
|
@@ -272,10 +292,11 @@ public class ECKeyUtil {
|
|
|
|
|
|
/**
|
|
|
* 将SM2算法的{@link ECPrivateKey} 转换为 {@link PrivateKey}
|
|
|
+ *
|
|
|
* @param privateKey {@link ECPrivateKey}
|
|
|
* @return {@link PrivateKey}
|
|
|
*/
|
|
|
- public static PrivateKey toSm2PrivateKey(ECPrivateKey privateKey){
|
|
|
+ public static PrivateKey toSm2PrivateKey(ECPrivateKey privateKey) {
|
|
|
try {
|
|
|
final PrivateKeyInfo info = new PrivateKeyInfo(
|
|
|
new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SmUtil.ID_SM2_PUBLIC_KEY_PARAM), privateKey);
|
|
|
@@ -284,4 +305,92 @@ public class ECKeyUtil {
|
|
|
throw new IORuntimeException(e);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建{@link OpenSSHPrivateKeySpec}
|
|
|
+ *
|
|
|
+ * @param key 私钥,需为PKCS#1格式
|
|
|
+ * @return {@link OpenSSHPrivateKeySpec}
|
|
|
+ * @since 5.5.9
|
|
|
+ */
|
|
|
+ public static KeySpec createOpenSSHPrivateKeySpec(byte[] key) {
|
|
|
+ return new OpenSSHPrivateKeySpec(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建{@link OpenSSHPublicKeySpec}
|
|
|
+ *
|
|
|
+ * @param key 公钥,需为PKCS#1格式
|
|
|
+ * @return {@link OpenSSHPublicKeySpec}
|
|
|
+ * @since 5.5.9
|
|
|
+ */
|
|
|
+ public static KeySpec createOpenSSHPublicKeySpec(byte[] key) {
|
|
|
+ return new OpenSSHPublicKeySpec(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 尝试解析转换各种类型私钥为{@link ECPrivateKeyParameters},支持包括:
|
|
|
+ *
|
|
|
+ * <ul>
|
|
|
+ * <li>D值</li>
|
|
|
+ * <li>PKCS#8</li>
|
|
|
+ * <li>PKCS#1</li>
|
|
|
+ * </ul>
|
|
|
+ *
|
|
|
+ * @param privateKeyBytes 私钥
|
|
|
+ * @return {@link ECPrivateKeyParameters}
|
|
|
+ * @since 5.5.9
|
|
|
+ */
|
|
|
+ public static ECPrivateKeyParameters decodePrivateKeyParams(byte[] privateKeyBytes) {
|
|
|
+ try {
|
|
|
+ // 尝试D值
|
|
|
+ return toSm2PrivateParams(privateKeyBytes);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+
|
|
|
+ PrivateKey privateKey;
|
|
|
+ //尝试PKCS#8
|
|
|
+ try {
|
|
|
+ privateKey = KeyUtil.generatePrivateKey("sm2", privateKeyBytes);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ // 尝试PKCS#1
|
|
|
+ privateKey = KeyUtil.generatePrivateKey("sm2", createOpenSSHPrivateKeySpec(privateKeyBytes));
|
|
|
+ }
|
|
|
+
|
|
|
+ return toPrivateParams(privateKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 尝试解析转换各种类型公钥为{@link ECPublicKeyParameters},支持包括:
|
|
|
+ *
|
|
|
+ * <ul>
|
|
|
+ * <li>Q值</li>
|
|
|
+ * <li>X.509</li>
|
|
|
+ * <li>PKCS#1</li>
|
|
|
+ * </ul>
|
|
|
+ *
|
|
|
+ * @param publicKeyBytes 公钥
|
|
|
+ * @return {@link ECPublicKeyParameters}
|
|
|
+ * @since 5.5.9
|
|
|
+ */
|
|
|
+ public static ECPublicKeyParameters decodePublicKeyParams(byte[] publicKeyBytes) {
|
|
|
+ try {
|
|
|
+ // 尝试Q值
|
|
|
+ return toSm2PublicParams(publicKeyBytes);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+
|
|
|
+ PublicKey publicKey;
|
|
|
+ //尝试X.509
|
|
|
+ try {
|
|
|
+ publicKey = KeyUtil.generatePublicKey("sm2", publicKeyBytes);
|
|
|
+ } catch (Exception ignore) {
|
|
|
+ // 尝试PKCS#1
|
|
|
+ publicKey = KeyUtil.generatePublicKey("sm2", createOpenSSHPublicKeySpec(publicKeyBytes));
|
|
|
+ }
|
|
|
+
|
|
|
+ return toPublicParams(publicKey);
|
|
|
+ }
|
|
|
}
|