Looly 6 年 前
コミット
e777fbf5ce

+ 1 - 0
CHANGELOG.md

@@ -7,6 +7,7 @@
 
 ### 新特性
 * 【core】        CollUtil增加filterNew等方法(原filter变更为filterNew,新增filter)
+* 【crypto】      Sign增加setParameter方法
 
 ### Bug修复
 

+ 17 - 2
hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java

@@ -49,7 +49,22 @@ public class RandomUtil {
 	}
 
 	/**
-	 * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
+	 * 创建{@link SecureRandom},类提供加密的强随机数生成器 (RNG)<br>
+	 * 
+	 * @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)<br>
+	 * 注意:此方法获取的是伪随机序列发生器PRNG(pseudo-random number generator)
+	 * 
+	 * <p>
+	 * 相关说明见: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值
 	 * 

+ 60 - 7
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 {
 	 * 生成用于非对称加密的公钥和私钥<br>
 	 * 密钥对生成算法见:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator
 	 * 
+	 * <p>
+	 * 对于非对称加密算法,密钥长度有严格限制,具体如下:
+	 * 
+	 * <p>
+	 * <b>RSA:</b>
+	 * <pre>
+	 * RS256、PS256:2048 bits
+	 * RS384、PS384:3072 bits
+	 * RS512、RS512:4096 bits
+	 * </pre>
+	 * 
+	 * <p>
+	 * <b>EC(Elliptic Curve):</b>
+	 * <pre>
+	 * EC256:256 bits
+	 * EC384:384 bits
+	 * EC512:512 bits
+	 * </pre>
+	 * 
 	 * @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);
+	}
+
+	/**
+	 * 生成用于非对称加密的公钥和私钥<br>
+	 * 密钥对生成算法见:https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator
+	 * 
+	 * <p>
+	 * 对于非对称加密算法,密钥长度有严格限制,具体如下:
+	 * 
+	 * <p>
+	 * <b>RSA:</b>
+	 * <pre>
+	 * RS256、PS256:2048 bits
+	 * RS384、PS384:3072 bits
+	 * RS512、RS512:4096 bits
+	 * </pre>
+	 * 
+	 * <p>
+	 * <b>EC(Elliptic Curve):</b>
+	 * <pre>
+	 * EC256:256 bits
+	 * EC384:384 bits
+	 * EC512:512 bits
+	 * </pre>
+	 * 
+	 * @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);
 					}

+ 1 - 1
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;

+ 18 - 0
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<Sign> {
 		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
 	/**

+ 3 - 0
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));
 

+ 1 - 1
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);
 

+ 6 - 1
hutool-http/src/main/java/cn/hutool/http/HttpRequest.java

@@ -862,7 +862,12 @@ public class HttpRequest extends HttpBase<HttpRequest> {
 
 	/**
 	 * 异步请求<br>
-	 * 异步请求后获取的{@link HttpResponse} 为异步模式,此时此对象持有Http链接(http链接并不会关闭),直调用获取内容方法为止
+	 * 异步请求后获取的{@link HttpResponse} 为异步模式,执行完此方法后发送请求到服务器,但是并不立即读取响应内容。<br>
+	 * 此时保持Http连接不关闭,直调用获取内容方法为止。
+	 * 
+	 * <p>
+	 * 一般执行完execute之后会把响应内容全部读出来放在一个 byte数组里,如果你响应的内容太多内存就爆了,此法是发送完请求不直接读响应内容,等有需要的时候读。
+
 	 * 
 	 * @return 异步对象,使用get方法获取HttpResponse对象
 	 */