diff --git a/CHANGELOG.md b/CHANGELOG.md index f0b0e1d60..f7115bfc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,12 +3,13 @@ ------------------------------------------------------------------------------------------------------------- -# 5.7.10 (2021-08-17) +# 5.7.10 (2021-08-18) ### 🐣新特性 * 【core 】 增加NamingCase类 * 【core 】 ListUtil增加page方法重载(pr#1761@Github) -* +* 【crypto 】 增加ASN1Util + ### 🐞Bug修复 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/ASN1Util.java b/hutool-crypto/src/main/java/cn/hutool/crypto/ASN1Util.java new file mode 100644 index 000000000..cc10d9602 --- /dev/null +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/ASN1Util.java @@ -0,0 +1,105 @@ +package cn.hutool.crypto; + +import cn.hutool.core.io.FastByteArrayOutputStream; +import cn.hutool.core.io.IORuntimeException; +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Encoding; +import org.bouncycastle.asn1.ASN1InputStream; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.BERSequence; +import org.bouncycastle.asn1.DERSequence; +import org.bouncycastle.asn1.DLSequence; +import org.bouncycastle.asn1.util.ASN1Dump; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * ASN.1 – Abstract Syntax Notation dot one,抽象记法1 工具类。
+ * ASN.1描述了一种对数据进行表示、编码、传输和解码的数据格式。它的编码格式包括DER、BER、DL等
+ * + * @author looly + * @since 5.7.10 + */ +public class ASN1Util { + + /** + * 编码为DER格式 + * + * @param elements ASN.1元素 + * @return 编码后的bytes + */ + public static byte[] encodeDer(ASN1Encodable... elements) { + return encode(ASN1Encoding.DER, elements); + } + + /** + * 编码为指定ASN1格式 + * + * @param asn1Encoding 编码格式,见{@link ASN1Encoding},可选DER、BER或DL + * @param elements ASN.1元素 + * @return 编码后的bytes + */ + public static byte[] encode(String asn1Encoding, ASN1Encodable... elements) { + final FastByteArrayOutputStream out = new FastByteArrayOutputStream(); + encodeTo(asn1Encoding, out, elements); + return out.toByteArray(); + } + + /** + * 编码为指定ASN1格式 + * + * @param asn1Encoding 编码格式,见{@link ASN1Encoding},可选DER、BER或DL + * @param out 输出流 + * @param elements ASN.1元素 + */ + public static void encodeTo(String asn1Encoding, OutputStream out, ASN1Encodable... elements) { + ASN1Sequence sequence; + switch (asn1Encoding) { + case ASN1Encoding.DER: + sequence = new DERSequence(elements); + break; + case ASN1Encoding.BER: + sequence = new BERSequence(elements); + break; + case ASN1Encoding.DL: + sequence = new DLSequence(elements); + break; + default: + throw new CryptoException("Unsupported ASN1 encoding: {}", asn1Encoding); + } + try { + sequence.encodeTo(out); + } catch (IOException e) { + throw new IORuntimeException(e); + } + } + + /** + * 读取ASN.1数据流为{@link ASN1Object} + * + * @param in ASN.1数据 + * @return {@link ASN1Object} + */ + public static ASN1Object decode(InputStream in) { + final ASN1InputStream asn1In = new ASN1InputStream(in); + try { + return asn1In.readObject(); + } catch (IOException e) { + throw new IORuntimeException(e); + } + } + + /** + * 获取ASN1格式的导出格式,一般用于调试 + * + * @param in ASN.1数据 + * @return {@link ASN1Object}的字符串表示形式 + * @see ASN1Dump#dumpAsString(Object) + */ + public static String getDumpStr(InputStream in) { + return ASN1Dump.dumpAsString(decode(in)); + } +} diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java index 283101da8..266f4ab4f 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/ECKeyUtil.java @@ -1,7 +1,6 @@ package cn.hutool.crypto; import cn.hutool.core.io.IORuntimeException; -import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.ECPrivateKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -300,7 +299,7 @@ public class ECKeyUtil { try { final PrivateKeyInfo info = new PrivateKeyInfo( new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SmUtil.ID_SM2_PUBLIC_KEY_PARAM), privateKey); - return KeyUtil.generatePrivateKey("SM2", info.getEncoded(ASN1Encoding.DER)); + return KeyUtil.generatePrivateKey("SM2", info.getEncoded()); } catch (IOException e) { throw new IORuntimeException(e); } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AbstractAsymmetricCrypto.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AbstractAsymmetricCrypto.java index 8a44f2ba7..82fe4ad9b 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AbstractAsymmetricCrypto.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AbstractAsymmetricCrypto.java @@ -106,7 +106,7 @@ public abstract class AbstractAsymmetricCrypto { // --------------------------------------------------------------------------------- Encrypt /** - * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中: + * 使用公钥加密,SM2非对称加密的结果由C1,C3,C2三部分组成,其中: * *
 	 * C1 生成随机数的计算出的椭圆曲线点
-	 * C2 密文数据
 	 * C3 SM3的摘要值
+	 * C2 密文数据
+	 * 
+ * + * @param data 被加密的bytes + * @return 加密后的bytes + * @throws CryptoException 包括InvalidKeyException和InvalidCipherTextException的包装异常 + * @since 5.7.10 + */ + public byte[] encrypt(byte[] data) throws CryptoException { + return encrypt(data, KeyType.PublicKey); + } + + /** + * 加密,SM2非对称加密的结果由C1,C3,C2三部分组成,其中: + * + *
+	 * C1 生成随机数的计算出的椭圆曲线点
+	 * C3 SM3的摘要值
+	 * C2 密文数据
 	 * 
* * @param data 被加密的bytes @@ -232,6 +250,18 @@ public class SM2 extends AbstractAsymmetricCrypto { // --------------------------------------------------------------------------------- Decrypt + /** + * 使用私钥解密 + * + * @param data SM2密文,实际包含三部分:ECC公钥、真正的密文、公钥和原文的SM3-HASH值 + * @return 加密后的bytes + * @throws CryptoException 包括InvalidKeyException和InvalidCipherTextException的包装异常 + * @since 5.7.10 + */ + public byte[] decrypt(byte[] data) throws CryptoException { + return decrypt(data, KeyType.PrivateKey); + } + /** * 解密 * diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java index ffb5e1dbc..9669bc277 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/asymmetric/SM2Test.java @@ -1,15 +1,18 @@ package cn.hutool.crypto.test.asymmetric; import cn.hutool.core.codec.Base64; +import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.crypto.ASN1Util; import cn.hutool.crypto.ECKeyUtil; import cn.hutool.crypto.KeyUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; +import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec; @@ -311,4 +314,10 @@ public class SM2Test { byte[] dec = sm2.decrypt(data, KeyType.PrivateKey); Assert.assertArrayEquals(dec, src.getBytes(StandardCharsets.UTF_8)); } + + @Test + public void asn1DecryptTest(){ + final SM2 sm2 = SmUtil.sm2("00dc7651c8473110a83215bfd26f37e306b2b99b02da9a4af9b9bd12e6360849bd", null); + final ASN1Sequence decode = (ASN1Sequence) ASN1Util.decode(ResourceUtil.getStream("asn1.key")); + } } diff --git a/hutool-crypto/src/test/resources/asn1.key b/hutool-crypto/src/test/resources/asn1.key new file mode 100644 index 000000000..79a36a858 Binary files /dev/null and b/hutool-crypto/src/test/resources/asn1.key differ diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index f196b3f7a..70e783f6d 100644 --- a/hutool-db/pom.xml +++ b/hutool-db/pom.xml @@ -81,7 +81,7 @@ com.github.chris2018998 beecp - 3.2.5 + 3.2.6 slf4j-api @@ -161,7 +161,7 @@ org.slf4j slf4j-simple - 1.7.30 + 1.7.32 test diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index adec1bc86..bb2f6d990 100644 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -19,10 +19,10 @@ 2.3 - 3.5.0.RELEASE + 3.5.1.RELEASE 1.4.1 2.3.31 - 4.9.15 + 4.9.16 3.0.12.RELEASE 1.6.2 0.1.55 @@ -235,7 +235,7 @@ com.hankcs hanlp - portable-1.7.8 + portable-1.8.2 true @@ -384,7 +384,7 @@ ch.qos.logback logback-classic - 1.2.3 + 1.2.5 test diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml index 6be98da2f..728e12b2b 100644 --- a/hutool-log/pom.xml +++ b/hutool-log/pom.xml @@ -18,7 +18,7 @@ - 1.7.30 + 1.7.32 1.3.0-alpha5 1.2.17 2.14.1 @@ -75,7 +75,7 @@ org.tinylog tinylog-api - 2.2.0 + 2.3.2 true @@ -99,7 +99,7 @@ org.tinylog tinylog-impl - 2.2.0 + 2.3.2 test diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index ad82f247d..134e75b5d 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -45,7 +45,7 @@ org.ofdrw ofdrw-full - 1.13.2 + 1.13.5 compile true