diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml
index 5515f8f5b..000d02103 100755
--- a/hutool-crypto/pom.xml
+++ b/hutool-crypto/pom.xml
@@ -18,7 +18,7 @@
- 1.70
+ 1.71
@@ -29,7 +29,7 @@
org.bouncycastle
- bcprov-jdk15to18
+ bcpkix-jdk15to18
${bouncycastle.version}
compile
true
diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/OpensslKeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/OpensslKeyUtil.java
new file mode 100644
index 000000000..6748a79ea
--- /dev/null
+++ b/hutool-crypto/src/main/java/cn/hutool/crypto/OpensslKeyUtil.java
@@ -0,0 +1,187 @@
+package cn.hutool.crypto;
+
+import cn.hutool.core.io.IORuntimeException;
+import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.openssl.PEMDecryptorProvider;
+import org.bouncycastle.openssl.PEMEncryptedKeyPair;
+import org.bouncycastle.openssl.PEMException;
+import org.bouncycastle.openssl.PEMKeyPair;
+import org.bouncycastle.openssl.PEMParser;
+import org.bouncycastle.openssl.X509TrustedCertificateBlock;
+import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
+import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
+import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
+import org.bouncycastle.operator.InputDecryptorProvider;
+import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.pkcs.PKCS10CertificationRequest;
+import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
+import org.bouncycastle.pkcs.PKCSException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+/**
+ * 基于bcpkix封装的Openssl相关工具,包括密钥转换、Pem密钥文件读取等
+ * 注意此工具需要引入org.bouncycastle:bcpkix-jdk15to18
+ *
+ * @author changhr2013, looly
+ * @since 5.8.5
+ */
+public class OpensslKeyUtil {
+
+ private static final JcaPEMKeyConverter pemKeyConverter = new JcaPEMKeyConverter().setProvider(GlobalBouncyCastleProvider.INSTANCE.getProvider());
+
+ /**
+ * 转换{@link PrivateKeyInfo}为{@link PrivateKey}
+ *
+ * @param privateKeyInfo {@link PrivateKeyInfo}
+ * @return {@link PrivateKey}
+ * @throws CryptoException {@link PEMException}包装
+ */
+ public static PrivateKey getPrivateKey(final PrivateKeyInfo privateKeyInfo) throws CryptoException {
+ try {
+ return pemKeyConverter.getPrivateKey(privateKeyInfo);
+ } catch (final PEMException e) {
+ throw new CryptoException(e);
+ }
+ }
+
+ /**
+ * 转换{@link SubjectPublicKeyInfo}为{@link PublicKey}
+ *
+ * @param publicKeyInfo {@link SubjectPublicKeyInfo}
+ * @return {@link PublicKey}
+ * @throws CryptoException {@link PEMException}包装
+ */
+ public static PublicKey getPublicKey(final SubjectPublicKeyInfo publicKeyInfo) throws CryptoException {
+ try {
+ return pemKeyConverter.getPublicKey(publicKeyInfo);
+ } catch (final PEMException e) {
+ throw new CryptoException(e);
+ }
+ }
+
+ /**
+ * 转换{@link PEMKeyPair}为{@link KeyPair}
+ *
+ * @param keyPair {@link PEMKeyPair}
+ * @return {@link KeyPair}
+ * @throws CryptoException {@link PEMException}包装
+ */
+ public static KeyPair getKeyPair(final PEMKeyPair keyPair) throws CryptoException {
+ try {
+ return pemKeyConverter.getKeyPair(keyPair);
+ } catch (final PEMException e) {
+ throw new CryptoException(e);
+ }
+ }
+
+ /**
+ * 从pem文件中读取公钥或私钥
+ * 根据类型返回 {@link PublicKey} 或者 {@link PrivateKey}
+ *
+ * @param keyStream pem 流
+ * @param password 私钥密码
+ * @return {@link Key},null 表示无法识别的密钥类型
+ * @since 5.8.5
+ */
+ public static Key readPemKey(final InputStream keyStream, final char[] password) {
+ try (final PEMParser pemParser = new PEMParser(new InputStreamReader(keyStream))) {
+ return readPemKeyFromKeyObject(pemParser.readObject(), password);
+ } catch (final IOException e) {
+ throw new CryptoException(e);
+ }
+ }
+
+ /**
+ * 解密{@link PKCS8EncryptedPrivateKeyInfo}为{@link PrivateKeyInfo}
+ *
+ * @param pkcs8Info {@link PKCS8EncryptedPrivateKeyInfo}
+ * @param password 密码
+ * @return {@link PrivateKeyInfo}
+ * @throws CryptoException OperatorCreationException和PKCSException包装
+ */
+ public static PrivateKeyInfo decrypt(final PKCS8EncryptedPrivateKeyInfo pkcs8Info, final char[] password) throws CryptoException {
+ final InputDecryptorProvider decryptProvider;
+ try {
+ decryptProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider(GlobalBouncyCastleProvider.INSTANCE.getProvider()).build(password);
+ return pkcs8Info.decryptPrivateKeyInfo(decryptProvider);
+ } catch (final OperatorCreationException | PKCSException e) {
+ throw new CryptoException(e);
+ }
+ }
+
+ /**
+ * 解密{@link PEMEncryptedKeyPair}为{@link PEMKeyPair}
+ *
+ * @param pemEncryptedKeyPair {@link PKCS8EncryptedPrivateKeyInfo}
+ * @param password 密码
+ * @return {@link PEMKeyPair}
+ * @throws IORuntimeException IOException包装
+ */
+ public static PEMKeyPair decrypt(final PEMEncryptedKeyPair pemEncryptedKeyPair, final char[] password) throws IORuntimeException {
+ final PEMDecryptorProvider decryptProvider;
+ try {
+ decryptProvider = new JcePEMDecryptorProviderBuilder().setProvider(GlobalBouncyCastleProvider.INSTANCE.getProvider()).build(password);
+ return pemEncryptedKeyPair.decryptKeyPair(decryptProvider);
+ } catch (final IOException e) {
+ throw new IORuntimeException(e);
+ }
+ }
+
+ /**
+ * 读取Pem文件中的密钥,密钥支持包括:
+ *
+ * - {@link PrivateKeyInfo}
+ * - {@link PEMKeyPair},默认读取私钥
+ * - {@link PKCS8EncryptedPrivateKeyInfo}
+ * - {@link PEMEncryptedKeyPair},默认读取私钥
+ * - {@link X509CertificateHolder}
+ * - {@link X509TrustedCertificateBlock}
+ * - {@link PKCS10CertificationRequest}
+ *
+ *
+ * @param keyObject 密钥内容对象
+ * @param password 密码(部分加密的pem使用)
+ * @return {@link Key}
+ * @throws CryptoException 读取异常或不支持的类型
+ */
+ private static Key readPemKeyFromKeyObject(final Object keyObject, final char[] password) throws CryptoException {
+ if (keyObject instanceof PrivateKeyInfo) {
+ // PrivateKeyInfo
+ return getPrivateKey((PrivateKeyInfo) keyObject);
+ } else if (keyObject instanceof PEMKeyPair) {
+ // PemKeyPair
+ return getKeyPair((PEMKeyPair) keyObject).getPrivate();
+ } else if (keyObject instanceof PKCS8EncryptedPrivateKeyInfo) {
+ // Encrypted PrivateKeyInfo
+ return getPrivateKey(decrypt((PKCS8EncryptedPrivateKeyInfo) keyObject, password));
+ } else if (keyObject instanceof PEMEncryptedKeyPair) {
+ // Encrypted PemKeyPair
+ return getPrivateKey(decrypt((PEMEncryptedKeyPair) keyObject, password).getPrivateKeyInfo());
+ } else if (keyObject instanceof SubjectPublicKeyInfo) {
+ // SubjectPublicKeyInfo
+ return getPublicKey((SubjectPublicKeyInfo) keyObject);
+ } else if (keyObject instanceof X509CertificateHolder) {
+ // X509 Certificate
+ return getPublicKey(((X509CertificateHolder) keyObject).getSubjectPublicKeyInfo());
+ } else if (keyObject instanceof X509TrustedCertificateBlock) {
+ // X509 Trusted Certificate
+ return getPublicKey(((X509TrustedCertificateBlock) keyObject).getCertificateHolder().getSubjectPublicKeyInfo());
+ } else if (keyObject instanceof PKCS10CertificationRequest) {
+ // PKCS#10 CSR
+ return getPublicKey(((PKCS10CertificationRequest) keyObject).getSubjectPublicKeyInfo());
+ } else {
+ // 表示无法识别的密钥类型
+ throw new CryptoException("Unsupported key object type: {}", keyObject.getClass());
+ }
+ }
+}
diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java
index af1b43428..c94d7fb60 100644
--- a/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java
+++ b/hutool-crypto/src/main/java/cn/hutool/crypto/PemUtil.java
@@ -67,7 +67,13 @@ public class PemUtil {
if (StrUtil.isNotBlank(type)) {
//private
if (type.endsWith("EC PRIVATE KEY")) {
- return KeyUtil.generatePrivateKey("EC", object.getContent());
+ try {
+ // 尝试PKCS#8
+ return KeyUtil.generatePrivateKey("EC", object.getContent());
+ } catch (final Exception e) {
+ // 尝试PKCS#1
+ return KeyUtil.generatePrivateKey("EC", ECKeyUtil.createOpenSSHPrivateKeySpec(object.getContent()));
+ }
}
if (type.endsWith("PRIVATE KEY")) {
return KeyUtil.generateRSAPrivateKey(object.getContent());
@@ -75,7 +81,13 @@ public class PemUtil {
// public
if (type.endsWith("EC PUBLIC KEY")) {
- return KeyUtil.generatePublicKey("EC", object.getContent());
+ try {
+ // 尝试DER
+ return KeyUtil.generatePublicKey("EC", object.getContent());
+ } catch (Exception e) {
+ // 尝试PKCS#1
+ return KeyUtil.generatePublicKey("EC", ECKeyUtil.createOpenSSHPublicKeySpec(object.getContent()));
+ }
} else if (type.endsWith("PUBLIC KEY")) {
return KeyUtil.generateRSAPublicKey(object.getContent());
} else if (type.endsWith("CERTIFICATE")) {
@@ -132,20 +144,6 @@ public class PemUtil {
}
}
- /**
- * 读取OpenSSL生成的ANS1格式的Pem私钥文件,必须为PKCS#1格式
- *
- * @param keyStream 私钥pem流
- * @return {@link PrivateKey}
- */
- public static PrivateKey readSm2PemPrivateKey(final InputStream keyStream) {
- try{
- return KeyUtil.generatePrivateKey("sm2", ECKeyUtil.createOpenSSHPrivateKeySpec(readPem(keyStream)));
- } finally {
- IoUtil.close(keyStream);
- }
- }
-
/**
* 将私钥或公钥转换为PEM格式的字符串
* @param type 密钥类型(私钥、公钥、证书)
diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/OpensslKeyUtilTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/OpensslKeyUtilTest.java
new file mode 100644
index 000000000..164f008d8
--- /dev/null
+++ b/hutool-crypto/src/test/java/cn/hutool/crypto/OpensslKeyUtilTest.java
@@ -0,0 +1,56 @@
+package cn.hutool.crypto;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.text.StrUtil;
+import cn.hutool.crypto.asymmetric.SM2;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.List;
+
+public class OpensslKeyUtilTest {
+
+ @Test
+ public void verifyPemUtilReadKey() {
+ // 公钥
+ // PKCS#10 文件读取公钥
+ final PublicKey csrPublicKey = (PublicKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_certificate_request.csr"), null);
+
+ // 证书读取公钥
+ final PublicKey certPublicKey = (PublicKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_certificate.cer"), null);
+
+ // PEM 公钥
+ final PublicKey plainPublicKey = (PublicKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_public_key.pem"), null);
+
+ // 私钥
+ // 加密的 PEM 私钥
+ final PrivateKey encPrivateKey = (PrivateKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_encrypted_private_key.key"), "123456".toCharArray());
+
+ // PKCS#8 私钥
+ final PrivateKey pkcs8PrivateKey = (PrivateKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_pkcs8_private_key.key"), null);
+
+ // SEC 1 私钥
+ final PrivateKey sec1PrivateKey = (PrivateKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_sec1_private_key.pem"), null);
+
+ // 组装还原后的公钥和私钥列表
+ final List publicKeyList = Arrays.asList(csrPublicKey, certPublicKey, plainPublicKey);
+ final List privateKeyList = Arrays.asList(encPrivateKey, pkcs8PrivateKey, sec1PrivateKey);
+
+ // 做笛卡尔积循环验证
+ for (final PrivateKey privateKeyItem : privateKeyList) {
+ for (final PublicKey publicKeyItem : publicKeyList) {
+ // 校验公私钥
+ final SM2 genSm2 = new SM2(privateKeyItem, publicKeyItem);
+ genSm2.usePlainEncoding();
+
+ final String content = "我是Hanley.";
+ final byte[] sign = genSm2.sign(StrUtil.utf8Bytes(content));
+ final boolean verify = genSm2.verify(StrUtil.utf8Bytes(content), sign);
+ Assert.assertTrue(verify);
+ }
+ }
+ }
+}
diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/PemUtilTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/PemUtilTest.java
index 099b452c7..86173e5d4 100644
--- a/hutool-crypto/src/test/java/cn/hutool/crypto/PemUtilTest.java
+++ b/hutool-crypto/src/test/java/cn/hutool/crypto/PemUtilTest.java
@@ -49,7 +49,21 @@ public class PemUtilTest {
@Test
public void readECPrivateKeyTest() {
- final PrivateKey privateKey = PemUtil.readSm2PemPrivateKey(ResourceUtil.getStream("test_ec_private_key.pem"));
+ final PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_private_key.pem"));
+ final SM2 sm2 = new SM2(privateKey, null);
+ sm2.usePlainEncoding();
+
+ //需要签名的明文,得到明文对应的字节数组
+ final byte[] dataBytes = "我是一段测试aaaa".getBytes(StandardCharsets.UTF_8);
+
+ final byte[] sign = sm2.sign(dataBytes, null);
+ // 64位签名
+ Assert.assertEquals(64, sign.length);
+ }
+
+ @Test
+ public void readECSec1PrivateKeyTest() {
+ final PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_sec1_private_key.pem"));
final SM2 sm2 = new SM2(privateKey, null);
sm2.usePlainEncoding();
diff --git a/hutool-crypto/src/test/resources/ test_ec_certificate.cer b/hutool-crypto/src/test/resources/ test_ec_certificate.cer
new file mode 100644
index 000000000..fcb41fa7a
--- /dev/null
+++ b/hutool-crypto/src/test/resources/ test_ec_certificate.cer
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBozCCAUegAwIBAgIIJQJK8f5oQVQwDAYIKoEcz1UBg3UFADAjMQswCQYDVQQG
+EwJDTjEUMBIGA1UEAwwLSHV0b29sIFRlc3QwHhcNMjIwNzE3MDcyMzU4WhcNMjMw
+NzE3MDcyMzU4WjAjMQswCQYDVQQGEwJDTjEUMBIGA1UEAwwLSHV0b29sIFRlc3Qw
+WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASXXjbO+6vY7vdD5aXoi2EMHUq0itI8
+kG6FN3cgLBFFoelyy3JxX94h7RpH4ylpNUXeRNuzv1VcPa06nsN1OjTWo2MwYTAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUFHvMM9CZ
+VUxWKt1+CHI5uYLpLgQwHwYDVR0jBBgwFoAUFHvMM9CZVUxWKt1+CHI5uYLpLgQw
+DAYIKoEcz1UBg3UFAANIADBFAiA5p0Gh7mvuuHMVG2SmbGj5HQpWcpwCaUF90BQ9
+/QEYZgIhAIXmeD2bDlOCPc3vxS4aNGxSd1wq/MT9bBJhKyiXWjx5
+-----END CERTIFICATE-----
diff --git a/hutool-crypto/src/test/resources/ test_ec_public_key.pem b/hutool-crypto/src/test/resources/ test_ec_public_key.pem
new file mode 100644
index 000000000..692d47b9f
--- /dev/null
+++ b/hutool-crypto/src/test/resources/ test_ec_public_key.pem
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEl142zvur2O73Q+Wl6IthDB1KtIrS
+PJBuhTd3ICwRRaHpcstycV/eIe0aR+MpaTVF3kTbs79VXD2tOp7DdTo01g==
+-----END PUBLIC KEY-----
diff --git a/hutool-crypto/src/test/resources/test_ec_certificate.cer b/hutool-crypto/src/test/resources/test_ec_certificate.cer
new file mode 100644
index 000000000..fcb41fa7a
--- /dev/null
+++ b/hutool-crypto/src/test/resources/test_ec_certificate.cer
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBozCCAUegAwIBAgIIJQJK8f5oQVQwDAYIKoEcz1UBg3UFADAjMQswCQYDVQQG
+EwJDTjEUMBIGA1UEAwwLSHV0b29sIFRlc3QwHhcNMjIwNzE3MDcyMzU4WhcNMjMw
+NzE3MDcyMzU4WjAjMQswCQYDVQQGEwJDTjEUMBIGA1UEAwwLSHV0b29sIFRlc3Qw
+WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASXXjbO+6vY7vdD5aXoi2EMHUq0itI8
+kG6FN3cgLBFFoelyy3JxX94h7RpH4ylpNUXeRNuzv1VcPa06nsN1OjTWo2MwYTAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUFHvMM9CZ
+VUxWKt1+CHI5uYLpLgQwHwYDVR0jBBgwFoAUFHvMM9CZVUxWKt1+CHI5uYLpLgQw
+DAYIKoEcz1UBg3UFAANIADBFAiA5p0Gh7mvuuHMVG2SmbGj5HQpWcpwCaUF90BQ9
+/QEYZgIhAIXmeD2bDlOCPc3vxS4aNGxSd1wq/MT9bBJhKyiXWjx5
+-----END CERTIFICATE-----
diff --git a/hutool-crypto/src/test/resources/test_ec_certificate_request.csr b/hutool-crypto/src/test/resources/test_ec_certificate_request.csr
new file mode 100644
index 000000000..9592662b8
--- /dev/null
+++ b/hutool-crypto/src/test/resources/test_ec_certificate_request.csr
@@ -0,0 +1,9 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBODCB3wIBADBWMQswCQYDVQQGEwJDTjEQMA4GA1UECBMHQmVpamluZzEQMA4G
+A1UEBxMHQmVpamluZzEPMA0GA1UECxMGSHV0b29sMRIwEAYDVQQDEwlodXRvb2wu
+Y24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASXXjbO+6vY7vdD5aXoi2EMHUq0
+itI8kG6FN3cgLBFFoelyy3JxX94h7RpH4ylpNUXeRNuzv1VcPa06nsN1OjTWoCcw
+JQYJKoZIhvcNAQkOMRgwFjAUBgNVHREEDTALgglodXRvb2wuY24wCgYIKoZIzj0E
+AwIDSAAwRQIhAIH0w1XbGnRfbM1flsqRHzfur+pEZ3wiqpChxAI39lpIAiAsNAwn
+o7PsXpTXLhq1ZgqurIjFeFuvY1hszUODmO5ySQ==
+-----END CERTIFICATE REQUEST-----
diff --git a/hutool-crypto/src/test/resources/test_ec_encrypted_private_key.key b/hutool-crypto/src/test/resources/test_ec_encrypted_private_key.key
new file mode 100644
index 000000000..dd3b2351f
--- /dev/null
+++ b/hutool-crypto/src/test/resources/test_ec_encrypted_private_key.key
@@ -0,0 +1,8 @@
+-----BEGIN EC PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,04b396b78c1f1172857a8b76682b63ef
+
+NoaLaSy87gLE6C3yCi7JwiB86NSYipZmMVlLIcHaBL2ECRUcGDmXEZu6OqFyrbDc
+XWXraEl3OieYduiVmuJ0GQ8oeWd5DNgHLBYTPnfgjBowbluAO9/R9AUh4R8Fz918
+/zsMZJckjSv3Gs6NWZW02v9OvhTDSJBNwu/M2WTWH10=
+-----END EC PRIVATE KEY-----
diff --git a/hutool-crypto/src/test/resources/test_ec_pkcs8_private_key.key b/hutool-crypto/src/test/resources/test_ec_pkcs8_private_key.key
new file mode 100644
index 000000000..e4b404e93
--- /dev/null
+++ b/hutool-crypto/src/test/resources/test_ec_pkcs8_private_key.key
@@ -0,0 +1,6 @@
+-----BEGIN PRIVATE KEY-----
+MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgEZmc6NdYu8UzpzhX
+1bcRzfWBlcGgnPtqfVsRzXfXZ/6gCgYIKoZIzj0DAQehRANCAASXXjbO+6vY7vdD
+5aXoi2EMHUq0itI8kG6FN3cgLBFFoelyy3JxX94h7RpH4ylpNUXeRNuzv1VcPa06
+nsN1OjTW
+-----END PRIVATE KEY-----
diff --git a/hutool-crypto/src/test/resources/test_ec_public_key.pem b/hutool-crypto/src/test/resources/test_ec_public_key.pem
new file mode 100644
index 000000000..692d47b9f
--- /dev/null
+++ b/hutool-crypto/src/test/resources/test_ec_public_key.pem
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEl142zvur2O73Q+Wl6IthDB1KtIrS
+PJBuhTd3ICwRRaHpcstycV/eIe0aR+MpaTVF3kTbs79VXD2tOp7DdTo01g==
+-----END PUBLIC KEY-----
diff --git a/hutool-crypto/src/test/resources/test_ec_sec1_private_key.pem b/hutool-crypto/src/test/resources/test_ec_sec1_private_key.pem
new file mode 100644
index 000000000..8b0b28be9
--- /dev/null
+++ b/hutool-crypto/src/test/resources/test_ec_sec1_private_key.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIBGZnOjXWLvFM6c4V9W3Ec31gZXBoJz7an1bEc1312f+oAoGCCqGSM49
+AwEHoUQDQgAEl142zvur2O73Q+Wl6IthDB1KtIrSPJBuhTd3ICwRRaHpcstycV/e
+Ie0aR+MpaTVF3kTbs79VXD2tOp7DdTo01g==
+-----END EC PRIVATE KEY-----