fix crypto

This commit is contained in:
Looly
2019-08-30 21:39:42 +08:00
parent f124fd0681
commit e777fbf5ce
8 changed files with 107 additions and 12 deletions

View File

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

View File

@@ -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>
* 注意此方法获取的是伪随机序列发生器PRNGpseudo-random number generator
*
* <p>
* 相关说明见https://stackoverflow.com/questions/137212/how-to-solve-slow-java-securerandom
* *
* @return {@link SecureRandom} * @return {@link SecureRandom}
* @since 3.1.2 * @since 3.1.2
@@ -74,7 +89,7 @@ public class RandomUtil {
public static Random getRandom(boolean isSecure) { public static Random getRandom(boolean isSecure) {
return isSecure ? getSecureRandom() : getRandom(); return isSecure ? getSecureRandom() : getRandom();
} }
/** /**
* 获得随机Boolean值 * 获得随机Boolean值
* *

View File

@@ -93,7 +93,7 @@ public class KeyUtil {
*/ */
public static SecretKey generateKey(String algorithm, int keySize) { public static SecretKey generateKey(String algorithm, int keySize) {
algorithm = getMainAlgorithm(algorithm); algorithm = getMainAlgorithm(algorithm);
final KeyGenerator keyGenerator = getKeyGenerator(algorithm); final KeyGenerator keyGenerator = getKeyGenerator(algorithm);
if (keySize > 0) { if (keySize > 0) {
keyGenerator.init(keySize); keyGenerator.init(keySize);
@@ -383,14 +383,67 @@ public class KeyUtil {
* 生成用于非对称加密的公钥和私钥<br> * 生成用于非对称加密的公钥和私钥<br>
* 密钥对生成算法见https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator * 密钥对生成算法见https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyPairGenerator
* *
* <p>
* 对于非对称加密算法,密钥长度有严格限制,具体如下:
*
* <p>
* <b>RSA</b>
* <pre>
* RS256、PS2562048 bits
* RS384、PS3843072 bits
* RS512、RS5124096 bits
* </pre>
*
* <p>
* <b>ECElliptic Curve</b>
* <pre>
* EC256256 bits
* EC384384 bits
* EC512512 bits
* </pre>
*
* @param algorithm 非对称加密算法 * @param algorithm 非对称加密算法
* @param keySize 密钥模modulus )长度 * @param keySize 密钥模modulus )长度单位bit
* @param seed 种子 * @param seed 种子
* @param params {@link AlgorithmParameterSpec} * @param params {@link AlgorithmParameterSpec}
* @return {@link KeyPair} * @return {@link KeyPair}
* @since 4.3.3 * @since 4.3.3
*/ */
public static KeyPair generateKeyPair(String algorithm, int keySize, byte[] seed, AlgorithmParameterSpec... params) { 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、PS2562048 bits
* RS384、PS3843072 bits
* RS512、RS5124096 bits
* </pre>
*
* <p>
* <b>ECElliptic Curve</b>
* <pre>
* EC256256 bits
* EC384384 bits
* EC512512 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); algorithm = getAlgorithmAfterWith(algorithm);
final KeyPairGenerator keyPairGen = getKeyPairGenerator(algorithm); final KeyPairGenerator keyPairGen = getKeyPairGenerator(algorithm);
@@ -398,11 +451,11 @@ public class KeyUtil {
if (keySize > 0) { if (keySize > 0) {
// key长度适配修正 // key长度适配修正
if ("EC".equalsIgnoreCase(algorithm) && keySize > 256) { if ("EC".equalsIgnoreCase(algorithm) && keySize > 256) {
// 对于EC算法密钥长度有限制在此使用默认256 // 对于ECEllipticCurve算法密钥长度有限制在此使用默认256
keySize = 256; keySize = 256;
} }
if (null != seed) { if (null != random) {
keyPairGen.initialize(keySize, new SecureRandom(seed)); keyPairGen.initialize(keySize, random);
} else { } else {
keyPairGen.initialize(keySize); keyPairGen.initialize(keySize);
} }
@@ -415,8 +468,8 @@ public class KeyUtil {
continue; continue;
} }
try { try {
if (null != seed) { if (null != random) {
keyPairGen.initialize(param, new SecureRandom(seed)); keyPairGen.initialize(param, random);
} else { } else {
keyPairGen.initialize(param); keyPairGen.initialize(param);
} }

View File

@@ -14,7 +14,7 @@ public enum AsymmetricAlgorithm {
RSA_ECB_PKCS1("RSA/ECB/PKCS1Padding"), RSA_ECB_PKCS1("RSA/ECB/PKCS1Padding"),
/** RSA算法此算法用了RSA/None/NoPadding */ /** RSA算法此算法用了RSA/None/NoPadding */
RSA_None("RSA/None/NoPadding"), RSA_None("RSA/None/NoPadding"),
/** EC算法 */ /** ECElliptic Curve算法 */
EC("EC"); EC("EC");
private String value; private String value;

View File

@@ -1,5 +1,6 @@
package cn.hutool.crypto.asymmetric; package cn.hutool.crypto.asymmetric;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
@@ -7,6 +8,7 @@ import java.security.PublicKey;
import java.security.Signature; import java.security.Signature;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Set; import java.util.Set;
import cn.hutool.core.codec.Base64; import cn.hutool.core.codec.Base64;
@@ -164,6 +166,22 @@ public class Sign extends BaseAsymmetric<Sign> {
super.init(algorithm, privateKey, publicKey); super.init(algorithm, privateKey, publicKey);
return this; 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 // --------------------------------------------------------------------------------- Sign and Verify
/** /**

View File

@@ -5,6 +5,7 @@ import java.security.KeyPair;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil; 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); 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); byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
Assert.assertEquals("我是一段测试aaaa", StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8)); Assert.assertEquals("我是一段测试aaaa", StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8));

View File

@@ -30,7 +30,7 @@ public class SymmetricTest {
// 随机生成密钥 // 随机生成密钥
byte[] key = KeyUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded(); byte[] key = KeyUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
// 构建 // 构建
SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key); SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

View File

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