From 2b30b8df247c469376a40133bb2d3b009ce65384 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 5 Sep 2024 13:23:47 +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 | 3 ++- .../hutool/core/convert/ConvertToBooleanTest.java | 10 +++++++++- .../main/java/cn/hutool/crypto/asymmetric/SM2.java | 13 +++++++++++++ .../java/cn/hutool/crypto/asymmetric/SM2Test.java | 13 +++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 101142105..b3b2d2167 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,13 @@ # 🚀Changelog ------------------------------------------------------------------------------------------------------------- -# 5.8.33(2024-09-04) +# 5.8.33(2024-09-05) ### 🐣新特性 * 【core 】 SyncFinisher增加setExecutorService方法(issue#IANKQ1@Gitee) * 【http 】 HttpConfig增加`setUseDefaultContentTypeIfNull`方法(issue#3719@Github) * 【core 】 用ArrayList重新实现权重随机类:WeightListRandom(pr#3720@Github) +* 【crypto 】 SM2解密时,兼容GmSSL非压缩省略的04头的密文(issue#IAP1QJ@Gitee) ### 🐞Bug修复 * 【json 】 修复JSONConfig.setDateFormat设置后toBean无效问题(issue#3713@Github) diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToBooleanTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToBooleanTest.java index 1c3a63574..a7d2f426b 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToBooleanTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/ConvertToBooleanTest.java @@ -1,8 +1,11 @@ package cn.hutool.core.convert; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class ConvertToBooleanTest { @Test @@ -15,4 +18,9 @@ public class ConvertToBooleanTest { final Boolean bBoolean = Convert.toBool(b); assertFalse(bBoolean); } + + @Test + void toBooleanWithDefaultTest() { + Assertions.assertFalse(Convert.toBool("ddddd", false)); + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java index e793430fd..58048a4d4 100755 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/SM2.java @@ -1,6 +1,7 @@ package cn.hutool.crypto.asymmetric; import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.crypto.BCUtil; import cn.hutool.crypto.CryptoException; @@ -292,6 +293,18 @@ public class SM2 extends AbstractAsymmetricCrypto { * @since 5.1.6 */ public byte[] decrypt(byte[] data, 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 = (byte[]) ArrayUtil.insert(data, 0, 0x04); + } + lock.lock(); final SM2Engine engine = getEngine(); try { diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java b/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java index bc8065cc4..9a8a24b04 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/asymmetric/SM2Test.java @@ -347,4 +347,17 @@ public class SM2Test { sm2.encryptHex(emptyStr, KeyType.PublicKey); }); } + + @Test + void decryptFromGmSSLTest() { + // https://the-x.cn/zh-cn/cryptography/Sm2.aspx + // python gmssl加密后的内容无04标识,检查并补充 + String privateKey = "MHcCAQEEICxTSOhWA4oYj2DI95zunPqHHEKZSi5QFLvWz57BfIGVoAoGCCqBHM9VAYItoUQDQgAEIGRS/PssvgZ8Paw2YeFaW4VXrkgceBELKPWcXmq/p3iMhHxYfcaFAa5AzvPJOmYmVzVwu9QygMMrg/30Ok1npw=="; + final SM2 sm2 = new SM2(privateKey, null); + sm2.setMode(SM2Engine.Mode.C1C2C3); + + String encrypt = "x0KA1DKkmuA/YZdmvMr8X+1ZQb7a19Pr5nSxxe2ItUYpDAioa263tm9u7vST38hAEUoOxxXftD+7bRQ7Y8v1tcFXeheKodetA6LrPIuh0QYZMdBqIKSKdmlGeVE0Vdm3excisbtC"; + final byte[] decrypt = sm2.decrypt(encrypt, KeyType.PrivateKey); + assertEquals("123456", StrUtil.utf8Str(decrypt)); + } }