From 02885bbcd3a5734def4c4884d5cdb0d42702e773 Mon Sep 17 00:00:00 2001 From: Looly Date: Thu, 9 Sep 2021 16:14:37 +0800 Subject: [PATCH] add ZUC --- CHANGELOG.md | 5 +- .../hutool/core/collection/AvgPartition.java | 2 + .../cn/hutool/core/collection/Partition.java | 5 +- .../hutool/core/collection/ListUtilTest.java | 18 +++- .../crypto/GlobalBouncyCastleProvider.java | 13 +-- .../cn/hutool/crypto/ProviderFactory.java | 8 +- .../java/cn/hutool/crypto/SecureUtil.java | 25 +++++ .../java/cn/hutool/crypto/digest/HMac.java | 15 ++- .../crypto/digest/mac/BCHMacEngine.java | 16 +++- .../crypto/digest/mac/DefaultHMacEngine.java | 58 +++++++++--- .../crypto/digest/mac/MacEngineFactory.java | 29 ++++-- .../java/cn/hutool/crypto/symmetric/ZUC.java | 92 +++++++++++++++++++ .../cn/hutool/crypto/symmetric/fpe/FPE.java | 8 +- .../hutool/crypto/test/digest/HmacTest.java | 60 ++++++++---- .../hutool/crypto/test/symmetric/ZucTest.java | 14 +-- .../src/test/resources/config/mail.setting | 2 +- hutool-poi/pom.xml | 2 +- 17 files changed, 303 insertions(+), 69 deletions(-) create mode 100644 hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/ZUC.java diff --git a/CHANGELOG.md b/CHANGELOG.md index cea88a96b..1a3935dc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------------------------------------- -# 5.7.12 (2021-09-08) +# 5.7.12 (2021-09-09) ### 🐣新特性 * 【system 】 OshiUtil增加getCurrentProcess方法 @@ -16,12 +16,13 @@ * 【core 】 ZipReader支持Filter * 【all 】 Sftp、Ftp、HttpDownloader增加download重载,支持避免传输文件损坏(pr#407@Gitee) * 【crypto 】 AES修改构造的IvParameterSpec为AlgorithmParameterSpec(issue#1814@Gitee) -* 【crypto 】 增加FPE(issue#1814@Gitee) +* 【crypto 】 增加FPE、ZUC(issue#1814@Gitee) ### 🐞Bug修复 * 【core 】 修复ListUtil.split方法越界问题(issue#I48Q0P@Gitee) * 【core 】 修复QrCode的isTryHarder、isPureBarcode设置无效问题(issue#1815@Github) * 【core 】 修复DatePattern.CHINESE_DATE_FORMATTER错误问题(issue#I48ZE3@Gitee) +* 【core 】 修复ListUtil.split错误问题 ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/AvgPartition.java b/hutool-core/src/main/java/cn/hutool/core/collection/AvgPartition.java index 48811f4af..d7ab3b5f7 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/AvgPartition.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/AvgPartition.java @@ -40,6 +40,8 @@ public class AvgPartition extends Partition { @Override public List get(int index) { + final int size = this.size; + final int remainder = this.remainder; // 当limit个数超过list的size时,size为0,此时每个分区分1个元素,直到remainder个分配完,剩余分区为[] int start = index * size + Math.min(index, remainder); int end = start + size; diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/Partition.java b/hutool-core/src/main/java/cn/hutool/core/collection/Partition.java index 3513d4711..fa555b974 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/Partition.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/Partition.java @@ -38,10 +38,11 @@ public class Partition extends AbstractList> { @Override public int size() { - // 此处采用动态计算,以应对list变化 + // 此处采用动态计算,以应对list变 + final int size = this.size; final int total = list.size(); int length = total / size; - if(total % length > 0){ + if(total % size > 0){ length += 1; } return length; diff --git a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java index 47a3b36de..5048de097 100644 --- a/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/collection/ListUtilTest.java @@ -18,11 +18,19 @@ public class ListUtilTest { @Test public void splitTest(){ - List listAll = new ArrayList<>(); - listAll.add("1"); - listAll.add("2"); - List> lists = ListUtil.split(listAll, 10); - Assert.assertEquals(1, lists.size()); + List> lists = ListUtil.split(null, 3); + Assert.assertEquals(ListUtil.empty(), lists); + + lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 1); + Assert.assertEquals("[[1], [2], [3], [4]]", lists.toString()); + lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 2); + Assert.assertEquals("[[1, 2], [3, 4]]", lists.toString()); + lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 3); + Assert.assertEquals("[[1, 2, 3], [4]]", lists.toString()); + lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 4); + Assert.assertEquals("[[1, 2, 3, 4]]", lists.toString()); + lists = ListUtil.split(Arrays.asList(1, 2, 3, 4), 5); + Assert.assertEquals("[[1, 2, 3, 4]]", lists.toString()); } @Test diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/GlobalBouncyCastleProvider.java b/hutool-crypto/src/main/java/cn/hutool/crypto/GlobalBouncyCastleProvider.java index 17f6c178e..d657ea917 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/GlobalBouncyCastleProvider.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/GlobalBouncyCastleProvider.java @@ -4,15 +4,15 @@ import java.security.Provider; /** * 全局单例的 org.bouncycastle.jce.provider.BouncyCastleProvider 对象 - * @author looly * + * @author looly */ public enum GlobalBouncyCastleProvider { INSTANCE; - + private Provider provider; private static boolean useBouncyCastle = true; - + GlobalBouncyCastleProvider() { try { this.provider = ProviderFactory.createBouncyCastleProvider(); @@ -20,19 +20,20 @@ public enum GlobalBouncyCastleProvider { // ignore } } - + /** * 获取{@link Provider} + * * @return {@link Provider} */ public Provider getProvider() { return useBouncyCastle ? this.provider : null; } - + /** * 设置是否使用Bouncy Castle库
* 如果设置为false,表示强制关闭Bouncy Castle而使用JDK - * + * * @param isUseBouncyCastle 是否使用BouncyCastle库 * @since 4.5.2 */ diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/ProviderFactory.java b/hutool-crypto/src/main/java/cn/hutool/crypto/ProviderFactory.java index 7ade30e79..9c52cba09 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/ProviderFactory.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/ProviderFactory.java @@ -3,12 +3,12 @@ package cn.hutool.crypto; import java.security.Provider; /** - * Provider对象生产法工厂类 - * + * Provider对象生产工厂类 + * *
  * 1. 调用{@link #createBouncyCastleProvider()} 用于新建一个org.bouncycastle.jce.provider.BouncyCastleProvider对象
  * 
- * + * * @author looly * @since 4.2.1 */ @@ -17,7 +17,7 @@ public class ProviderFactory { /** * 创建Bouncy Castle 提供者
* 如果用户未引入bouncycastle库,则此方法抛出{@link NoClassDefFoundError} 异常 - * + * * @return {@link Provider} */ public static Provider createBouncyCastleProvider() { diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java index c8bf7f778..2353195aa 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/SecureUtil.java @@ -21,6 +21,7 @@ import cn.hutool.crypto.symmetric.DESede; import cn.hutool.crypto.symmetric.PBKDF2; import cn.hutool.crypto.symmetric.RC4; import cn.hutool.crypto.symmetric.SymmetricCrypto; +import cn.hutool.crypto.symmetric.ZUC; import cn.hutool.crypto.symmetric.fpe.FPE; import org.bouncycastle.crypto.AlphabetMapper; @@ -1124,4 +1125,28 @@ public class SecureUtil { public static FPE fpe(FPE.FPEMode mode, byte[] key, AlphabetMapper mapper, byte[] tweak) { return new FPE(mode, key, mapper, tweak); } + + /** + * 祖冲之算法集(ZUC-128算法)实现,基于BouncyCastle实现。 + * + * @param key 密钥 + * @param iv 加盐,长度16bytes,{@code null}是随机加盐 + * @return {@link ZUC} + * @since 5.7.12 + */ + public static ZUC zuc128(byte[] key, byte[] iv) { + return new ZUC(ZUC.ZUCAlgorithm.ZUC_128, key, iv); + } + + /** + * 祖冲之算法集(ZUC-256算法)实现,基于BouncyCastle实现。 + * + * @param key 密钥 + * @param iv 加盐,长度25bytes,{@code null}是随机加盐 + * @return {@link ZUC} + * @since 5.7.12 + */ + public static ZUC zuc256(byte[] key, byte[] iv) { + return new ZUC(ZUC.ZUCAlgorithm.ZUC_256, key, iv); + } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/HMac.java b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/HMac.java index fc3180b5f..e6c916b6c 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/HMac.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/HMac.java @@ -18,6 +18,7 @@ import java.io.Serializable; import java.nio.charset.Charset; import java.security.Key; import java.security.MessageDigest; +import java.security.spec.AlgorithmParameterSpec; /** * HMAC摘要算法
@@ -84,7 +85,19 @@ public class HMac implements Serializable { * @since 4.5.13 */ public HMac(String algorithm, Key key) { - this(MacEngineFactory.createEngine(algorithm, key)); + this(algorithm, key, null); + } + + /** + * 构造 + * + * @param algorithm 算法 + * @param key 密钥 + * @param spec {@link AlgorithmParameterSpec} + * @since 5.6.12 + */ + public HMac(String algorithm, Key key, AlgorithmParameterSpec spec) { + this(MacEngineFactory.createEngine(algorithm, key, spec)); } /** diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/BCHMacEngine.java b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/BCHMacEngine.java index 0b78412b4..b734dd86d 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/BCHMacEngine.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/BCHMacEngine.java @@ -5,6 +5,7 @@ import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; /** * BouncyCastle的HMAC算法实现引擎,使用{@link Mac} 实现摘要
@@ -18,11 +19,24 @@ public class BCHMacEngine implements MacEngine { private Mac mac; // ------------------------------------------------------------------------------------------- Constructor start + /** * 构造 * * @param digest 摘要算法,为{@link Digest} 的接口实现 - * @param key 密钥 + * @param key 密钥 + * @param iv 加盐 + * @since 5.7.12 + */ + public BCHMacEngine(Digest digest, byte[] key, byte[] iv) { + this(digest, new ParametersWithIV(new KeyParameter(key), iv)); + } + + /** + * 构造 + * + * @param digest 摘要算法,为{@link Digest} 的接口实现 + * @param key 密钥 * @since 4.5.13 */ public BCHMacEngine(Digest digest, byte[] key) { diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/DefaultHMacEngine.java b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/DefaultHMacEngine.java index 679764890..1adf6f9be 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/DefaultHMacEngine.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/DefaultHMacEngine.java @@ -7,64 +7,100 @@ import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.security.Key; +import java.security.spec.AlgorithmParameterSpec; /** * 默认的HMAC算法实现引擎,使用{@link Mac} 实现摘要
* 当引入BouncyCastle库时自动使用其作为Provider * * @author Looly - *@since 4.5.13 + * @since 4.5.13 */ public class DefaultHMacEngine implements MacEngine { private Mac mac; // ------------------------------------------------------------------------------------------- Constructor start + /** * 构造 + * * @param algorithm 算法 - * @param key 密钥 + * @param key 密钥 * @since 4.5.13 */ public DefaultHMacEngine(String algorithm, byte[] key) { - init(algorithm, key); + this(algorithm, (null == key) ? null : new SecretKeySpec(key, algorithm)); } /** * 构造 + * * @param algorithm 算法 - * @param key 密钥 + * @param key 密钥 * @since 4.5.13 */ public DefaultHMacEngine(String algorithm, Key key) { - init(algorithm, key); + this(algorithm, key, null); + } + + /** + * 构造 + * + * @param algorithm 算法 + * @param key 密钥 + * @param spec {@link AlgorithmParameterSpec} + * @since 5.7.12 + */ + public DefaultHMacEngine(String algorithm, Key key, AlgorithmParameterSpec spec) { + init(algorithm, key, spec); } // ------------------------------------------------------------------------------------------- Constructor end /** * 初始化 + * * @param algorithm 算法 - * @param key 密钥 + * @param key 密钥 * @return this */ - public DefaultHMacEngine init(String algorithm, byte[] key){ + public DefaultHMacEngine init(String algorithm, byte[] key) { return init(algorithm, (null == key) ? null : new SecretKeySpec(key, algorithm)); } /** * 初始化 + * * @param algorithm 算法 - * @param key 密钥 {@link SecretKey} + * @param key 密钥 {@link SecretKey} * @return this * @throws CryptoException Cause by IOException */ - public DefaultHMacEngine init(String algorithm, Key key){ + public DefaultHMacEngine init(String algorithm, Key key) { + return init(algorithm, key, null); + } + + /** + * 初始化 + * + * @param algorithm 算法 + * @param key 密钥 {@link SecretKey} + * @param spec {@link AlgorithmParameterSpec} + * @return this + * @throws CryptoException Cause by IOException + * @since 5.7.12 + */ + public DefaultHMacEngine init(String algorithm, Key key, AlgorithmParameterSpec spec) { try { mac = SecureUtil.createMac(algorithm); - if(null == key){ + if (null == key) { key = SecureUtil.generateKey(algorithm); } - mac.init(key); + if (null != spec) { + mac.init(key, spec); + } else { + mac.init(key); + } } catch (Exception e) { throw new CryptoException(e); } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/MacEngineFactory.java b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/MacEngineFactory.java index 4ec1a485c..47efa47eb 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/MacEngineFactory.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/digest/mac/MacEngineFactory.java @@ -4,26 +4,41 @@ import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.digest.HmacAlgorithm; import java.security.Key; +import java.security.spec.AlgorithmParameterSpec; /** * {@link MacEngine} 实现工厂类 - * + * * @author Looly - *@since 4.5.13 + * @since 4.5.13 */ public class MacEngineFactory { - + /** * 根据给定算法和密钥生成对应的{@link MacEngine} + * * @param algorithm 算法,见{@link HmacAlgorithm} - * @param key 密钥 + * @param key 密钥 * @return {@link MacEngine} */ public static MacEngine createEngine(String algorithm, Key key) { - if(algorithm.equalsIgnoreCase(HmacAlgorithm.HmacSM3.getValue())) { - // HmacSM3算法是BC库实现的 + return createEngine(algorithm, key, null); + } + + /** + * 根据给定算法和密钥生成对应的{@link MacEngine} + * + * @param algorithm 算法,见{@link HmacAlgorithm} + * @param key 密钥 + * @param spec spec + * @return {@link MacEngine} + * @since 5.7.12 + */ + public static MacEngine createEngine(String algorithm, Key key, AlgorithmParameterSpec spec) { + if (algorithm.equalsIgnoreCase(HmacAlgorithm.HmacSM3.getValue())) { + // HmacSM3算法是BC库实现的,忽略加盐 return SmUtil.createHmacSm3Engine(key.getEncoded()); } - return new DefaultHMacEngine(algorithm, key); + return new DefaultHMacEngine(algorithm, key, spec); } } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/ZUC.java b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/ZUC.java new file mode 100644 index 000000000..30291776f --- /dev/null +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/ZUC.java @@ -0,0 +1,92 @@ +package cn.hutool.crypto.symmetric; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.crypto.KeyUtil; + +import javax.crypto.spec.IvParameterSpec; + +/** + * 祖冲之算法集(ZUC算法)实现,基于BouncyCastle实现。 + * + * @author looly + * @since 5.7.12 + */ +public class ZUC extends SymmetricCrypto { + private static final long serialVersionUID = 1L; + + /** + * 生成ZUC算法密钥 + * + * @param algorithm ZUC算法 + * @return 密钥 + * + * @see KeyUtil#generateKey(String) + */ + public static byte[] generateKey(ZUCAlgorithm algorithm) { + return KeyUtil.generateKey(algorithm.value).getEncoded(); + } + + /** + * 构造 + * + * @param algorithm ZUC算法枚举,包括128位和256位两种 + * @param key 密钥 + * @param iv 加盐,128位加盐是16bytes,256位是25bytes,{@code null}是随机加盐 + */ + public ZUC(ZUCAlgorithm algorithm, byte[] key, byte[] iv) { + super(algorithm.value, + KeyUtil.generateKey(algorithm.value, key), + generateIvParam(algorithm, iv)); + } + + /** + * ZUC类型,包括128位和256位 + * + * @author looly + */ + public enum ZUCAlgorithm { + ZUC_128("ZUC-128"), + ZUC_256("ZUC-256"); + + private final String value; + + /** + * 构造 + * + * @param value 算法的字符串表示,区分大小写 + */ + ZUCAlgorithm(String value) { + this.value = value; + } + + /** + * 获得算法的字符串表示形式 + * + * @return 算法字符串 + */ + public String getValue() { + return this.value; + } + } + + /** + * 生成加盐参数 + * + * @param algorithm ZUC算法 + * @param iv 加盐,128位加盐是16bytes,256位是25bytes,{@code null}是随机加盐 + * @return {@link IvParameterSpec} + */ + private static IvParameterSpec generateIvParam(ZUCAlgorithm algorithm, byte[] iv){ + if(null == iv){ + switch (algorithm){ + case ZUC_128: + iv = RandomUtil.randomBytes(16); + break; + case ZUC_256: + iv = RandomUtil.randomBytes(25); + break; + } + } + return new IvParameterSpec(iv); + } +} diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/fpe/FPE.java b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/fpe/FPE.java index 06c3d21ae..b6cfd1e59 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/fpe/FPE.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/symmetric/fpe/FPE.java @@ -25,6 +25,8 @@ import java.io.Serializable; *
  • 加密过程可逆,加密后的数据可以通过密钥解密还原原始数据
  • * * + * 此类基于BouncyCastle实现。 + * * @author looly * @since 5.7.12 */ @@ -52,15 +54,15 @@ public class FPE implements Serializable { * @param mode FPE模式枚举,可选FF1或FF3-1 * @param key 密钥,{@code null}表示随机密钥,长度必须是16bit、24bit或32bit * @param mapper Alphabet字典映射,被加密的字符范围和这个映射必须一致,例如手机号、银行卡号等字段可以采用数字字母字典表 - * @param tweak Tweak是为了解决因局部加密而导致结果冲突问题,通常情况下将数据的不可变部分作为Tweak + * @param tweak Tweak是为了解决因局部加密而导致结果冲突问题,通常情况下将数据的不可变部分作为Tweak,{@code null}使用默认长度全是0的bytes */ public FPE(FPEMode mode, byte[] key, AlphabetMapper mapper, byte[] tweak) { if (null == mode) { mode = FPEMode.FF1; } - if(null == tweak){ - switch (mode){ + if (null == tweak) { + switch (mode) { case FF1: tweak = new byte[0]; break; diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/digest/HmacTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/digest/HmacTest.java index 80ea6e451..5254a127e 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/digest/HmacTest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/digest/HmacTest.java @@ -1,13 +1,16 @@ package cn.hutool.crypto.test.digest; -import org.junit.Assert; -import org.junit.Test; - import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.CharsetUtil; +import cn.hutool.crypto.KeyUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.digest.HMac; import cn.hutool.crypto.digest.HmacAlgorithm; +import cn.hutool.crypto.symmetric.ZUC; +import org.junit.Assert; +import org.junit.Test; + +import javax.crypto.spec.IvParameterSpec; /** * Hmac单元测试 @@ -15,44 +18,69 @@ import cn.hutool.crypto.digest.HmacAlgorithm; * */ public class HmacTest { - + @Test public void hmacTest(){ String testStr = "test中文"; - + byte[] key = "password".getBytes(); HMac mac = new HMac(HmacAlgorithm.HmacMD5, key); - + String macHex1 = mac.digestHex(testStr); Assert.assertEquals("b977f4b13f93f549e06140971bded384", macHex1); - + String macHex2 = mac.digestHex(IoUtil.toStream(testStr, CharsetUtil.CHARSET_UTF_8)); Assert.assertEquals("b977f4b13f93f549e06140971bded384", macHex2); } - + @Test public void hmacMd5Test(){ String testStr = "test中文"; - + HMac mac = SecureUtil.hmacMd5("password"); - + String macHex1 = mac.digestHex(testStr); Assert.assertEquals("b977f4b13f93f549e06140971bded384", macHex1); - + String macHex2 = mac.digestHex(IoUtil.toStream(testStr, CharsetUtil.CHARSET_UTF_8)); Assert.assertEquals("b977f4b13f93f549e06140971bded384", macHex2); } - + @Test public void hmacSha1Test(){ - String testStr = "test中文"; - HMac mac = SecureUtil.hmacSha1("password"); - + + String testStr = "test中文"; String macHex1 = mac.digestHex(testStr); Assert.assertEquals("1dd68d2f119d5640f0d416e99d3f42408b88d511", macHex1); - + String macHex2 = mac.digestHex(IoUtil.toStream(testStr, CharsetUtil.CHARSET_UTF_8)); Assert.assertEquals("1dd68d2f119d5640f0d416e99d3f42408b88d511", macHex2); } + + @Test + public void zuc128MacTest(){ + byte[] iv = new byte[16]; + final byte[] key = new byte[16]; + HMac mac = new HMac("ZUC-128", + KeyUtil.generateKey(ZUC.ZUCAlgorithm.ZUC_128.getValue(), key), + new IvParameterSpec(iv)); + + String testStr = "test中文"; + String macHex1 = mac.digestHex(testStr); + Assert.assertEquals("1e0b9455", macHex1); + } + + @Test + public void zuc256MacTest(){ + byte[] iv = new byte[25]; + final byte[] key = new byte[32]; + HMac mac = new HMac("ZUC-256", + KeyUtil.generateKey(ZUC.ZUCAlgorithm.ZUC_128.getValue(), key), + new IvParameterSpec(iv)); + + String testStr = "test中文"; + String macHex1 = mac.digestHex(testStr); + Assert.assertEquals("d9ad618357c1bfb1d9d1200a763d5eaa", macHex1); + } } diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/ZucTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/ZucTest.java index 1f81f7f7f..81524d95c 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/ZucTest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/symmetric/ZucTest.java @@ -2,21 +2,17 @@ package cn.hutool.crypto.test.symmetric; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.RandomUtil; -import cn.hutool.crypto.KeyUtil; -import cn.hutool.crypto.symmetric.SymmetricCrypto; +import cn.hutool.crypto.symmetric.ZUC; import org.junit.Assert; import org.junit.Test; -import javax.crypto.SecretKey; -import javax.crypto.spec.IvParameterSpec; - public class ZucTest { @Test public void zuc128Test(){ - final SecretKey secretKey = KeyUtil.generateKey("zuc-128"); + final byte[] secretKey = ZUC.generateKey(ZUC.ZUCAlgorithm.ZUC_128); byte[] iv = RandomUtil.randomBytes(16); - final SymmetricCrypto zuc = new SymmetricCrypto("zuc-128", secretKey, new IvParameterSpec(iv)); + final ZUC zuc = new ZUC(ZUC.ZUCAlgorithm.ZUC_128, secretKey, iv); String msg = RandomUtil.randomString(500); byte[] crypt2 = zuc.encrypt(msg); @@ -26,9 +22,9 @@ public class ZucTest { @Test public void zuc256Test(){ - final SecretKey secretKey = KeyUtil.generateKey("zuc-256"); + final byte[] secretKey = ZUC.generateKey(ZUC.ZUCAlgorithm.ZUC_256); byte[] iv = RandomUtil.randomBytes(25); - final SymmetricCrypto zuc = new SymmetricCrypto("zuc-256", secretKey, new IvParameterSpec(iv)); + final ZUC zuc = new ZUC(ZUC.ZUCAlgorithm.ZUC_256, secretKey, iv); String msg = RandomUtil.randomString(500); byte[] crypt2 = zuc.encrypt(msg); diff --git a/hutool-extra/src/test/resources/config/mail.setting b/hutool-extra/src/test/resources/config/mail.setting index 43c97da19..a7aa08342 100644 --- a/hutool-extra/src/test/resources/config/mail.setting +++ b/hutool-extra/src/test/resources/config/mail.setting @@ -19,4 +19,4 @@ starttlsEnable = true # 是否开启SSL sslEnable = true # 调试模式 -debug = true \ No newline at end of file +debug = true diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 12697bdc6..62a094b7e 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -45,7 +45,7 @@ org.ofdrw ofdrw-full - 1.15.0 + 1.15.1 compile true