diff --git a/CHANGELOG.md b/CHANGELOG.md index 019977385..20b958460 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### 新特性 * 【core】 CollUtil增加filterNew等方法(原filter变更为filterNew,新增filter) +* 【crypto】 Sign增加setParameter方法 ### Bug修复 diff --git a/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java index e6c3f6fc2..cc4cbd803 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java @@ -49,7 +49,22 @@ public class RandomUtil { } /** - * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) + * 创建{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
+ * + * @param seed 自定义随机种子 + * @return {@link SecureRandom} + * @since 4.6.5 + */ + public static SecureRandom createSecureRandom(byte[] seed) { + return (null == seed) ? new SecureRandom() : new SecureRandom(seed); + } + + /** + * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
+ * 注意:此方法获取的是伪随机序列发生器PRNG(pseudo-random number generator) + * + *

+ * 相关说明见:https://stackoverflow.com/questions/137212/how-to-solve-slow-java-securerandom * * @return {@link SecureRandom} * @since 3.1.2 @@ -74,7 +89,7 @@ public class RandomUtil { public static Random getRandom(boolean isSecure) { return isSecure ? getSecureRandom() : getRandom(); } - + /** * 获得随机Boolean值 * diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java b/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java index 09f05aeb0..ce3dc2c45 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/KeyUtil.java @@ -93,7 +93,7 @@ public class KeyUtil { */ public static SecretKey generateKey(String algorithm, int keySize) { algorithm = getMainAlgorithm(algorithm); - + final KeyGenerator keyGenerator = getKeyGenerator(algorithm); if (keySize > 0) { keyGenerator.init(keySize); @@ -383,14 +383,67 @@ public class KeyUtil { * 生成用于非对称加密的公钥和私钥
* 密钥对生成算法见:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator * + *

+ * 对于非对称加密算法,密钥长度有严格限制,具体如下: + * + *

+ * RSA: + *

+	 * RS256、PS256:2048 bits
+	 * RS384、PS384:3072 bits
+	 * RS512、RS512:4096 bits
+	 * 
+ * + *

+ * EC(Elliptic Curve): + *

+	 * EC256:256 bits
+	 * EC384:384 bits
+	 * EC512:512 bits
+	 * 
+ * * @param algorithm 非对称加密算法 - * @param keySize 密钥模(modulus )长度 + * @param keySize 密钥模(modulus )长度(单位bit) * @param seed 种子 * @param params {@link AlgorithmParameterSpec} * @return {@link KeyPair} * @since 4.3.3 */ public static KeyPair generateKeyPair(String algorithm, int keySize, byte[] seed, AlgorithmParameterSpec... params) { + return generateKeyPair(algorithm, keySize, RandomUtil.createSecureRandom(seed), params); + } + + /** + * 生成用于非对称加密的公钥和私钥
+ * 密钥对生成算法见:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator + * + *

+ * 对于非对称加密算法,密钥长度有严格限制,具体如下: + * + *

+ * RSA: + *

+	 * RS256、PS256:2048 bits
+	 * RS384、PS384:3072 bits
+	 * RS512、RS512:4096 bits
+	 * 
+ * + *

+ * EC(Elliptic Curve): + *

+	 * EC256:256 bits
+	 * EC384:384 bits
+	 * EC512:512 bits
+	 * 
+ * + * @param algorithm 非对称加密算法 + * @param keySize 密钥模(modulus )长度(单位bit) + * @param random {@link SecureRandom} 对象,创建时可选传入seed + * @param params {@link AlgorithmParameterSpec} + * @return {@link KeyPair} + * @since 4.6.5 + */ + public static KeyPair generateKeyPair(String algorithm, int keySize, SecureRandom random, AlgorithmParameterSpec... params) { algorithm = getAlgorithmAfterWith(algorithm); final KeyPairGenerator keyPairGen = getKeyPairGenerator(algorithm); @@ -398,11 +451,11 @@ public class KeyUtil { if (keySize > 0) { // key长度适配修正 if ("EC".equalsIgnoreCase(algorithm) && keySize > 256) { - // 对于EC算法,密钥长度有限制,在此使用默认256 + // 对于EC(EllipticCurve)算法,密钥长度有限制,在此使用默认256 keySize = 256; } - if (null != seed) { - keyPairGen.initialize(keySize, new SecureRandom(seed)); + if (null != random) { + keyPairGen.initialize(keySize, random); } else { keyPairGen.initialize(keySize); } @@ -415,8 +468,8 @@ public class KeyUtil { continue; } try { - if (null != seed) { - keyPairGen.initialize(param, new SecureRandom(seed)); + if (null != random) { + keyPairGen.initialize(param, random); } else { keyPairGen.initialize(param); } diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AsymmetricAlgorithm.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AsymmetricAlgorithm.java index ecd398392..13e82f459 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AsymmetricAlgorithm.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/AsymmetricAlgorithm.java @@ -14,7 +14,7 @@ public enum AsymmetricAlgorithm { RSA_ECB_PKCS1("RSA/ECB/PKCS1Padding"), /** RSA算法,此算法用了RSA/None/NoPadding */ RSA_None("RSA/None/NoPadding"), - /** EC算法 */ + /** EC(Elliptic Curve)算法 */ EC("EC"); private String value; diff --git a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/Sign.java b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/Sign.java index 281e10bf0..81c67a3ae 100644 --- a/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/Sign.java +++ b/hutool-crypto/src/main/java/cn/hutool/crypto/asymmetric/Sign.java @@ -1,5 +1,6 @@ package cn.hutool.crypto.asymmetric; +import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; @@ -7,6 +8,7 @@ import java.security.PublicKey; import java.security.Signature; import java.security.cert.Certificate; import java.security.cert.X509Certificate; +import java.security.spec.AlgorithmParameterSpec; import java.util.Set; import cn.hutool.core.codec.Base64; @@ -164,6 +166,22 @@ public class Sign extends BaseAsymmetric { super.init(algorithm, privateKey, publicKey); return this; } + + /** + * 设置签名的参数 + * + * @param params {@link AlgorithmParameterSpec} + * @return this + * @since 4.6.5 + */ + public Sign setParameter(AlgorithmParameterSpec params) { + try { + this.signature.setParameter(params); + } catch (InvalidAlgorithmParameterException e) { + throw new CryptoException(e); + } + return this; + } // --------------------------------------------------------------------------------- Sign and Verify /** diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/RSATest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/RSATest.java index 8a706225e..e488d6c1f 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/RSATest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/RSATest.java @@ -5,6 +5,7 @@ import java.security.KeyPair; import org.junit.Assert; import org.junit.Test; +import cn.hutool.core.lang.Console; import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.StrUtil; @@ -59,6 +60,8 @@ public class RSATest { // 公钥加密,私钥解密 byte[] encrypt = rsa.encrypt(StrUtil.bytes("我是一段测试aaaa", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey); + Console.log(HexUtil.encodeHexStr(encrypt)); + byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey); Assert.assertEquals("我是一段测试aaaa", StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8)); diff --git a/hutool-crypto/src/test/java/cn/hutool/crypto/test/SymmetricTest.java b/hutool-crypto/src/test/java/cn/hutool/crypto/test/SymmetricTest.java index 8d5960ca7..d4fedc5f1 100644 --- a/hutool-crypto/src/test/java/cn/hutool/crypto/test/SymmetricTest.java +++ b/hutool-crypto/src/test/java/cn/hutool/crypto/test/SymmetricTest.java @@ -30,7 +30,7 @@ public class SymmetricTest { // 随机生成密钥 byte[] key = KeyUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded(); - + // 构建 SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key); diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java index 732477197..01ad928b8 100644 --- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java +++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java @@ -862,7 +862,12 @@ public class HttpRequest extends HttpBase { /** * 异步请求
- * 异步请求后获取的{@link HttpResponse} 为异步模式,此时此对象持有Http链接(http链接并不会关闭),直调用获取内容方法为止 + * 异步请求后获取的{@link HttpResponse} 为异步模式,执行完此方法后发送请求到服务器,但是并不立即读取响应内容。
+ * 此时保持Http连接不关闭,直调用获取内容方法为止。 + * + *

+ * 一般执行完execute之后会把响应内容全部读出来放在一个 byte数组里,如果你响应的内容太多内存就爆了,此法是发送完请求不直接读响应内容,等有需要的时候读。 + * * @return 异步对象,使用get方法获取HttpResponse对象 */