From 38911594c83d5b877b78219db5c5b224e7250e7c Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 5 Sep 2024 13:23:37 +0800 Subject: [PATCH] =?UTF-8?q?SM2=E8=A7=A3=E5=AF=86=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=85=BC=E5=AE=B9GmSSL=E9=9D=9E=E5=8E=8B=E7=BC=A9=E7=9C=81?= =?UTF-8?q?=E7=95=A5=E7=9A=8404=E5=A4=B4=E7=9A=84=E5=AF=86=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 - .../core/convert/ConvertToBooleanTest.java | 5 + .../dromara/hutool/crypto/asymmetric/SM2.java | 16 ++- .../hutool/crypto/asymmetric/SM2Test.java | 15 +++ .../db/meta/DatabaseMetaDataWrapper.java | 2 +- .../org/dromara/hutool/db/meta/IndexInfo.java | 102 +++++++++++++++--- .../org/dromara/hutool/db/meta/TableType.java | 25 ++++- 7 files changed, 146 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62b62bbd2..4189f9bbe 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,10 @@ ### 计划实现 * 【db 】 增加DDL封装 -* 【poi 】 CellUtil.getCellIfMergedRegion考虑添加缓存支持,增加最大和最小范围判断,减少遍历 * 【http 】 redirect跳转和Cookie ### ❌不兼容特性 ### 🐣新特性 -* 【db 】 优化count查询兼容informix(issue#I713XQ@Gitee) ### 🐞Bug修复 \ No newline at end of file diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToBooleanTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToBooleanTest.java index 5f1b91020..ec68c3d2c 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToBooleanTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/convert/ConvertToBooleanTest.java @@ -34,4 +34,9 @@ public class ConvertToBooleanTest { Assertions.assertFalse(bool); } + @Test + void toBooleanWithDefaultTest() { + Assertions.assertFalse(ConvertUtil.toBoolean("ddddd", false)); + } + } diff --git a/hutool-crypto/src/main/java/org/dromara/hutool/crypto/asymmetric/SM2.java b/hutool-crypto/src/main/java/org/dromara/hutool/crypto/asymmetric/SM2.java index bdce23f8d..cbc897066 100644 --- a/hutool-crypto/src/main/java/org/dromara/hutool/crypto/asymmetric/SM2.java +++ b/hutool-crypto/src/main/java/org/dromara/hutool/crypto/asymmetric/SM2.java @@ -31,6 +31,7 @@ import org.bouncycastle.crypto.signers.SM2Signer; import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.encoders.Hex; +import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.codec.binary.HexUtil; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.crypto.CryptoException; @@ -313,7 +314,20 @@ public class SM2 extends AbstractAsymmetricCrypto { * @throws CryptoException 包括InvalidKeyException和InvalidCipherTextException的包装异常 * @since 5.1.6 */ - public byte[] decrypt(final byte[] data, final CipherParameters privateKeyParameters) throws CryptoException { + public byte[] decrypt(byte[] data, final CipherParameters privateKeyParameters) throws CryptoException { + Assert.isTrue(data.length > 1, "Invalid SM2 cipher text, must be at least 1 byte long"); + // 检查数据,gmssl等库生成的密文不包含04前缀(非压缩数据标识),此处检查并补充 + // 参考:https://blog.csdn.net/softt/article/details/139978608 + // 根据公钥压缩形态不同,密文分为两种压缩形式: + // C1( 03 + X ) + C3(32个字节)+ C2 + // C1( 02 + X ) + C3(32个字节)+ C2 + // 非压缩公钥正常形态为04 + X + Y,由于各个算法库差异,04有时候会省略 + // 非压缩密文正常形态为04 + C1 + C3 + C2 + if (data[0] != 0x04 && data[0] != 0x02 && data[0] != 0x03) { + // 默认非压缩形态 + data = ArrayUtil.insert(data, 0, 0x04); + } + lock.lock(); final SM2Engine engine = getEngine(); try { diff --git a/hutool-crypto/src/test/java/org/dromara/hutool/crypto/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/org/dromara/hutool/crypto/asymmetric/SM2Test.java index eab019cfe..cd3caf01f 100644 --- a/hutool-crypto/src/test/java/org/dromara/hutool/crypto/asymmetric/SM2Test.java +++ b/hutool-crypto/src/test/java/org/dromara/hutool/crypto/asymmetric/SM2Test.java @@ -32,6 +32,8 @@ import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * SM2算法单元测试 * @@ -333,4 +335,17 @@ public class SM2Test { Assertions.assertNotNull(sm1); Assertions.assertNotNull(sm2); } + + @Test + void decryptFromGmSSLTest() { + // https://the-x.cn/zh-cn/cryptography/Sm2.aspx + // python gmssl加密后的内容无04标识,检查并补充 + final String privateKey = "MHcCAQEEICxTSOhWA4oYj2DI95zunPqHHEKZSi5QFLvWz57BfIGVoAoGCCqBHM9VAYItoUQDQgAEIGRS/PssvgZ8Paw2YeFaW4VXrkgceBELKPWcXmq/p3iMhHxYfcaFAa5AzvPJOmYmVzVwu9QygMMrg/30Ok1npw=="; + final SM2 sm2 = new SM2(privateKey, null); + sm2.setMode(SM2Engine.Mode.C1C2C3); + + final String encrypt = "x0KA1DKkmuA/YZdmvMr8X+1ZQb7a19Pr5nSxxe2ItUYpDAioa263tm9u7vST38hAEUoOxxXftD+7bRQ7Y8v1tcFXeheKodetA6LrPIuh0QYZMdBqIKSKdmlGeVE0Vdm3excisbtC"; + final byte[] decrypt = sm2.decrypt(encrypt, KeyType.PrivateKey); + assertEquals("123456", StrUtil.utf8Str(decrypt)); + } } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/meta/DatabaseMetaDataWrapper.java b/hutool-db/src/main/java/org/dromara/hutool/db/meta/DatabaseMetaDataWrapper.java index b58194ba9..dfd1de3e1 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/meta/DatabaseMetaDataWrapper.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/meta/DatabaseMetaDataWrapper.java @@ -159,7 +159,7 @@ public class DatabaseMetaDataWrapper extends SimpleWrapper { // issue#I9BANE Oracle中特殊表名需要解包 tableName = getPureTableName(tableName); - try (final ResultSet rs = this.raw.getTables(catalog, schema, tableName, new String[]{TableType.TABLE.value()})) { + try (final ResultSet rs = this.raw.getTables(catalog, schema, tableName, new String[]{TableType.TABLE.getValue()})) { if (null != rs) { if (rs.next()) { return rs.getString("REMARKS"); diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/meta/IndexInfo.java b/hutool-db/src/main/java/org/dromara/hutool/db/meta/IndexInfo.java index 301aecc61..449a49089 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/meta/IndexInfo.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/meta/IndexInfo.java @@ -77,55 +77,127 @@ public class IndexInfo implements Serializable, Cloneable { this.tableName = tableName; this.schema = schema; this.catalog = catalog; - this.setColumnIndexInfoList(new ArrayList<>()); + this.columnIndexInfoList = new ArrayList<>(); } + /** + * 检查索引是否是非唯一的 + * + * @return 如果索引是非唯一的,返回true;否则返回false + */ public boolean isNonUnique() { return nonUnique; } - public void setNonUnique(final boolean nonUnique) { + /** + * 设置索引的非唯一状态 + * + * @param nonUnique 索引的非唯一状态 + * @return 当前的IndexInfo对象,以支持链式调用 + */ + public IndexInfo setNonUnique(final boolean nonUnique) { this.nonUnique = nonUnique; + return this; } + /** + * 获取索引名称 + * + * @return 索引名称 + */ public String getIndexName() { return indexName; } - public void setIndexName(final String indexName) { + /** + * 设置索引名称 + * + * @param indexName 索引名称 + * @return 当前的IndexInfo对象,以支持链式调用 + */ + public IndexInfo setIndexName(final String indexName) { this.indexName = indexName; + return this; } + /** + * 获取表名称 + * + * @return 表名称 + */ public String getTableName() { return tableName; } - public void setTableName(final String tableName) { + /** + * 设置表名称 + * + * @param tableName 表名称 + * @return 当前的IndexInfo对象,以支持链式调用 + */ + public IndexInfo setTableName(final String tableName) { this.tableName = tableName; + return this; } + /** + * 获取 schema 名称 + * + * @return schema 名称 + */ public String getSchema() { return schema; } - public void setSchema(final String schema) { + /** + * 设置 schema 名称 + * + * @param schema schema 名称 + * @return 当前的IndexInfo对象,以支持链式调用 + */ + public IndexInfo setSchema(final String schema) { this.schema = schema; + return this; } + /** + * 获取目录名称 + * + * @return 目录名称 + */ public String getCatalog() { return catalog; } - public void setCatalog(final String catalog) { + /** + * 设置目录名称 + * + * @param catalog 目录名称 + * @return 当前的IndexInfo对象,以支持链式调用 + */ + public IndexInfo setCatalog(final String catalog) { this.catalog = catalog; + return this; } + /** + * 获取列索引信息列表 + * + * @return 列索引信息列表 + */ public List getColumnIndexInfoList() { return columnIndexInfoList; } - public void setColumnIndexInfoList(final List columnIndexInfoList) { + /** + * 设置列索引信息列表 + * + * @param columnIndexInfoList 列索引信息列表 + * @return 当前的IndexInfo对象,以支持链式调用 + */ + public IndexInfo setColumnIndexInfoList(final List columnIndexInfoList) { this.columnIndexInfoList = columnIndexInfoList; + return this; } @Override @@ -138,7 +210,7 @@ public class IndexInfo implements Serializable, Cloneable { } final IndexInfo indexInfo = (IndexInfo) o; return ObjUtil.equals(indexName, indexInfo.indexName) - && ObjUtil.equals(tableName, indexInfo.tableName); + && ObjUtil.equals(tableName, indexInfo.tableName); } @Override @@ -154,12 +226,12 @@ public class IndexInfo implements Serializable, Cloneable { @Override public String toString() { return "IndexInfo{" + - "nonUnique=" + nonUnique + - ", indexName='" + indexName + '\'' + - ", tableName='" + tableName + '\'' + - ", schema='" + schema + '\'' + - ", catalog='" + catalog + '\'' + - ", columnIndexInfoList=" + columnIndexInfoList + - '}'; + "nonUnique=" + nonUnique + + ", indexName='" + indexName + '\'' + + ", tableName='" + tableName + '\'' + + ", schema='" + schema + '\'' + + ", catalog='" + catalog + '\'' + + ", columnIndexInfoList=" + columnIndexInfoList + + '}'; } } diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/meta/TableType.java b/hutool-db/src/main/java/org/dromara/hutool/db/meta/TableType.java index 2958c05a7..6e9a21fac 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/meta/TableType.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/meta/TableType.java @@ -22,12 +22,33 @@ package org.dromara.hutool.db.meta; * @author Looly */ public enum TableType { + /** + * 数据库表 + */ TABLE("TABLE"), + /** + * 视图 + */ VIEW("VIEW"), + /** + * 系统表 + */ SYSTEM_TABLE("SYSTEM TABLE"), + /** + * 全局临时表 + */ GLOBAL_TEMPORARY("GLOBAL TEMPORARY"), + /** + * 本地临时表 + */ LOCAL_TEMPORARY("LOCAL TEMPORARY"), + /** + * 别名 + */ ALIAS("ALIAS"), + /** + * 快捷方式 + */ SYNONYM("SYNONYM"); private final String value; @@ -46,12 +67,12 @@ public enum TableType { * * @return 值 */ - public String value() { + public String getValue() { return this.value; } @Override public String toString() { - return this.value(); + return this.getValue(); } }