|
|
@@ -1,5 +1,6 @@
|
|
|
package cn.hutool.crypto;
|
|
|
|
|
|
+import cn.hutool.core.util.HexUtil;
|
|
|
import org.bouncycastle.crypto.params.ECDomainParameters;
|
|
|
import org.bouncycastle.crypto.params.ECKeyParameters;
|
|
|
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
|
|
@@ -14,7 +15,7 @@ import org.bouncycastle.jce.spec.ECNamedCurveSpec;
|
|
|
import org.bouncycastle.jce.spec.ECParameterSpec;
|
|
|
import org.bouncycastle.math.ec.ECCurve;
|
|
|
|
|
|
-import java.io.InputStream;
|
|
|
+import java.math.BigInteger;
|
|
|
import java.security.GeneralSecurityException;
|
|
|
import java.security.KeyFactory;
|
|
|
import java.security.PrivateKey;
|
|
|
@@ -31,6 +32,18 @@ import java.security.spec.EllipticCurve;
|
|
|
* @since 4.5.0
|
|
|
*/
|
|
|
public class BCUtil {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 只获取私钥里的d,32字节
|
|
|
+ *
|
|
|
+ * @param privateKey {@link PublicKey},必须为org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
|
|
|
+ * @return 压缩得到的X
|
|
|
+ * @since 5.1.6
|
|
|
+ */
|
|
|
+ public static byte[] encodeECPrivateKey(PrivateKey privateKey) {
|
|
|
+ return ((BCECPrivateKey) privateKey).getD().toByteArray();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 编码压缩EC公钥(基于BouncyCastle)<br>
|
|
|
* 见:https://www.cnblogs.com/xinzhao/p/8963724.html
|
|
|
@@ -95,7 +108,7 @@ public class BCUtil {
|
|
|
*/
|
|
|
public static ECKeyParameters toParams(ECKey ecKey) {
|
|
|
final ECParameterSpec parameterSpec = ecKey.getParameters();
|
|
|
- final ECDomainParameters ecDomainParameters = buildECDomainParameters(parameterSpec);
|
|
|
+ final ECDomainParameters ecDomainParameters = toDomainParameters(parameterSpec);
|
|
|
|
|
|
if (ecKey instanceof BCECPrivateKey) {
|
|
|
return new ECPrivateKeyParameters(((BCECPrivateKey) ecKey).getD(), ecDomainParameters);
|
|
|
@@ -113,11 +126,124 @@ public class BCUtil {
|
|
|
* @return ECDomainParameters
|
|
|
* @since 5.1.6
|
|
|
*/
|
|
|
- public static ECDomainParameters buildECDomainParameters(ECParameterSpec parameterSpec) {
|
|
|
+ public static ECDomainParameters toDomainParameters(ECParameterSpec parameterSpec) {
|
|
|
return new ECDomainParameters(
|
|
|
parameterSpec.getCurve(),
|
|
|
parameterSpec.getG(),
|
|
|
parameterSpec.getN(),
|
|
|
parameterSpec.getH());
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换为 ECPrivateKeyParameters
|
|
|
+ *
|
|
|
+ * @param dHex 私钥d值16进制字符串
|
|
|
+ * @param domainParameters ECDomainParameters
|
|
|
+ * @return ECPrivateKeyParameters
|
|
|
+ */
|
|
|
+ public static ECPrivateKeyParameters toParams(String dHex, ECDomainParameters domainParameters) {
|
|
|
+ return new ECPrivateKeyParameters(new BigInteger(dHex, 16), domainParameters);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换为 ECPrivateKeyParameters
|
|
|
+ *
|
|
|
+ * @param d 私钥d值
|
|
|
+ * @param domainParameters ECDomainParameters
|
|
|
+ * @return ECPrivateKeyParameters
|
|
|
+ */
|
|
|
+ public static ECPrivateKeyParameters toParams(BigInteger d, ECDomainParameters domainParameters) {
|
|
|
+ return new ECPrivateKeyParameters(d, domainParameters);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换为ECPublicKeyParameters
|
|
|
+ *
|
|
|
+ * @param x 公钥X
|
|
|
+ * @param y 公钥Y
|
|
|
+ * @param curve ECCurve
|
|
|
+ * @param domainParameters ECDomainParameters
|
|
|
+ * @return ECPublicKeyParameters
|
|
|
+ */
|
|
|
+ public static ECPublicKeyParameters toParams(BigInteger x, BigInteger y, ECCurve curve, ECDomainParameters domainParameters) {
|
|
|
+ return toParams(x.toByteArray(), y.toByteArray(), curve, domainParameters);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换为ECPublicKeyParameters
|
|
|
+ *
|
|
|
+ * @param xHex 公钥X
|
|
|
+ * @param yHex 公钥Y
|
|
|
+ * @param curve ECCurve
|
|
|
+ * @param domainParameters ECDomainParameters
|
|
|
+ * @return ECPublicKeyParameters
|
|
|
+ */
|
|
|
+ public static ECPublicKeyParameters toParams(String xHex, String yHex, ECCurve curve, ECDomainParameters domainParameters) {
|
|
|
+ return toParams(HexUtil.decodeHex(xHex), HexUtil.decodeHex(yHex),
|
|
|
+ curve, domainParameters);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换为ECPublicKeyParameters
|
|
|
+ *
|
|
|
+ * @param xBytes 公钥X
|
|
|
+ * @param yBytes 公钥Y
|
|
|
+ * @param curve ECCurve
|
|
|
+ * @param domainParameters ECDomainParameters
|
|
|
+ * @return ECPublicKeyParameters
|
|
|
+ */
|
|
|
+ public static ECPublicKeyParameters toParams(byte[] xBytes, byte[] yBytes, ECCurve curve, ECDomainParameters domainParameters) {
|
|
|
+ final byte uncompressedFlag = 0x04;
|
|
|
+ int curveLength = getCurveLength(domainParameters);
|
|
|
+ xBytes = fixLength(curveLength, xBytes);
|
|
|
+ yBytes = fixLength(curveLength, yBytes);
|
|
|
+ byte[] encodedPubKey = new byte[1 + xBytes.length + yBytes.length];
|
|
|
+ encodedPubKey[0] = uncompressedFlag;
|
|
|
+ System.arraycopy(xBytes, 0, encodedPubKey, 1, xBytes.length);
|
|
|
+ System.arraycopy(yBytes, 0, encodedPubKey, 1 + xBytes.length, yBytes.length);
|
|
|
+ return new ECPublicKeyParameters(curve.decodePoint(encodedPubKey), domainParameters);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取Curve长度
|
|
|
+ *
|
|
|
+ * @param ecKey Curve
|
|
|
+ * @return Curve长度
|
|
|
+ */
|
|
|
+ public static int getCurveLength(ECKeyParameters ecKey) {
|
|
|
+ return getCurveLength(ecKey.getParameters());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取Curve长度
|
|
|
+ *
|
|
|
+ * @param domainParams ECDomainParameters
|
|
|
+ * @return Curve长度
|
|
|
+ */
|
|
|
+ public static int getCurveLength(ECDomainParameters domainParams) {
|
|
|
+ return (domainParams.getCurve().getFieldSize() + 7) / 8;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修正长度
|
|
|
+ *
|
|
|
+ * @param curveLength 修正后的长度
|
|
|
+ * @param src bytes
|
|
|
+ * @return 修正后的bytes
|
|
|
+ */
|
|
|
+ private static byte[] fixLength(int curveLength, byte[] src) {
|
|
|
+ if (src.length == curveLength) {
|
|
|
+ return src;
|
|
|
+ }
|
|
|
+
|
|
|
+ byte[] result = new byte[curveLength];
|
|
|
+ if (src.length > curveLength) {
|
|
|
+ // 裁剪末尾的指定长度
|
|
|
+ System.arraycopy(src, src.length - result.length, result, 0, result.length);
|
|
|
+ } else {
|
|
|
+ // 放置于末尾
|
|
|
+ System.arraycopy(src, 0, result, result.length - src.length, src.length);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|