This commit is contained in:
Looly 2023-04-12 17:23:09 +08:00
parent a96a95c988
commit a7c18e81f6
38 changed files with 426 additions and 175 deletions

View File

@ -140,15 +140,35 @@ public class TextSimilarity {
/** /**
* 求公共子串采用动态规划算法 其不要求所求得的字符在所给的字符串中是连续的 * 求公共子串采用动态规划算法 其不要求所求得的字符在所给的字符串中是连续的
* 2023-04-06 优化堆内存占用此处不需要matrix[m][n]的完整矩阵仅需右下角值
* *
* @param strA 字符串1 * @param strA 字符串1
* @param strB 字符串2 * @param strB 字符串2
* @return 公共子串 * @return 公共子串
*/ */
private static int longestCommonSubstringLength(final String strA, final String strB) { public static int longestCommonSubstringLength(final String strA, final String strB) {
final int m = strA.length(); final int m = strA.length();
final int n = strB.length(); final int n = strB.length();
return generateMatrix(strA, strB)[m][n];
// 初始化矩阵数据,matrix[0][0]的值为0 如果字符数组chars_strA和chars_strB的对应位相同则matrix[i][j]的值为左上角的值加1
// 否则matrix[i][j]的值等于左上方最近两个位置的较大值 矩阵中其余各点的值为0.
int[] lastLine = new int[n + 1];
int[] currLine = new int[n + 1];
int[] temp;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (strA.charAt(i - 1) == strB.charAt(j - 1)) {
currLine[j] = lastLine[j-1] + 1;
} else {
currLine[j] = Math.max(currLine[j-1], lastLine[j]);
}
}
temp = lastLine;
lastLine = currLine;
currLine = temp;
}
return lastLine[n];
} }
/** /**

View File

@ -1,12 +1,15 @@
package org.dromara.hutool.core.text; package org.dromara.hutool.core.text;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.util.RandomUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
/** /**
* 文本相似度计算工具类单元测试 * 文本相似度计算工具类单元测试
* @author looly
* *
* @author looly
*/ */
public class TextSimilarityTest { public class TextSimilarityTest {
@ -35,8 +38,20 @@ public class TextSimilarityTest {
} }
@Test @Test
public void similarTest(){ public void similarTest() {
final double abd = TextSimilarity.similar("abd", "1111"); final double abd = TextSimilarity.similar("abd", "1111");
Assertions.assertEquals(0, abd, 1); Assertions.assertEquals(0, abd, 1);
} }
@Test
@Disabled
void longestCommonSubstringLengthTest() {
// https://github.com/dromara/hutool/issues/3045
final String strCommon = RandomUtil.randomString(1024 * 32);
final String strA = RandomUtil.randomString(1024 * 32) + strCommon;
final String strB = RandomUtil.randomString(1024 * 32) + strCommon;
final int i = TextSimilarity.longestCommonSubstringLength(strA, strB);
Console.log(i);
}
} }

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto;
import java.security.Provider;
/**
* 全局单例的 org.bouncycastle.jce.provider.BouncyCastleProvider 对象
*
* @author looly
*/
public enum GlobalBouncyCastleProvider {
/**
* 单例对象
*/
INSTANCE;
private Provider provider;
private static boolean useBouncyCastle = true;
GlobalBouncyCastleProvider() {
try {
this.provider = ProviderFactory.createBouncyCastleProvider();
} catch (final NoClassDefFoundError | NoSuchMethodError e) {
// ignore
}
}
/**
* 获取{@link Provider}
*
* @return {@link Provider}
*/
public Provider getProvider() {
return useBouncyCastle ? this.provider : null;
}
/**
* 设置是否使用Bouncy Castle库<br>
* 如果设置为false表示强制关闭Bouncy Castle而使用JDK
*
* @param isUseBouncyCastle 是否使用BouncyCastle库
* @since 4.5.2
*/
public static void setUseBouncyCastle(final boolean isUseBouncyCastle) {
useBouncyCastle = isUseBouncyCastle;
}
}

View File

@ -21,6 +21,9 @@ import org.dromara.hutool.core.util.CharUtil;
import org.dromara.hutool.core.util.RandomUtil; import org.dromara.hutool.core.util.RandomUtil;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.crypto.asymmetric.AsymmetricAlgorithm; import org.dromara.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import org.dromara.hutool.crypto.bc.BCUtil;
import org.dromara.hutool.crypto.bc.SmUtil;
import org.dromara.hutool.crypto.provider.GlobalProviderFactory;
import org.dromara.hutool.crypto.symmetric.SymmetricAlgorithm; import org.dromara.hutool.crypto.symmetric.SymmetricAlgorithm;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
@ -553,7 +556,7 @@ public class KeyUtil {
* @since 4.4.3 * @since 4.4.3
*/ */
public static KeyPairGenerator getKeyPairGenerator(final String algorithm) { public static KeyPairGenerator getKeyPairGenerator(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final KeyPairGenerator keyPairGen; final KeyPairGenerator keyPairGen;
try { try {
@ -574,7 +577,7 @@ public class KeyUtil {
* @since 4.4.4 * @since 4.4.4
*/ */
public static KeyFactory getKeyFactory(final String algorithm) { public static KeyFactory getKeyFactory(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final KeyFactory keyFactory; final KeyFactory keyFactory;
try { try {
@ -595,7 +598,7 @@ public class KeyUtil {
* @since 4.5.2 * @since 4.5.2
*/ */
public static SecretKeyFactory getSecretKeyFactory(final String algorithm) { public static SecretKeyFactory getSecretKeyFactory(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final SecretKeyFactory keyFactory; final SecretKeyFactory keyFactory;
try { try {
@ -616,7 +619,7 @@ public class KeyUtil {
* @since 4.5.2 * @since 4.5.2
*/ */
public static KeyGenerator getKeyGenerator(final String algorithm) { public static KeyGenerator getKeyGenerator(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final KeyGenerator generator; final KeyGenerator generator;
try { try {
@ -773,7 +776,7 @@ public class KeyUtil {
* @return {@link KeyStore} * @return {@link KeyStore}
*/ */
public static KeyStore getKeyStore(final String type) { public static KeyStore getKeyStore(final String type) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
try { try {
return null == provider ? KeyStore.getInstance(type) : KeyStore.getInstance(type, provider); return null == provider ? KeyStore.getInstance(type) : KeyStore.getInstance(type, provider);
} catch (final KeyStoreException e) { } catch (final KeyStoreException e) {
@ -923,7 +926,7 @@ public class KeyUtil {
* @since 4.5.0 * @since 4.5.0
*/ */
public static CertificateFactory getCertificateFactory(final String type) { public static CertificateFactory getCertificateFactory(final String type) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final CertificateFactory factory; final CertificateFactory factory;
try { try {

View File

@ -24,6 +24,7 @@ import org.dromara.hutool.crypto.digest.Digester;
import org.dromara.hutool.crypto.digest.HMac; import org.dromara.hutool.crypto.digest.HMac;
import org.dromara.hutool.crypto.digest.HmacAlgorithm; import org.dromara.hutool.crypto.digest.HmacAlgorithm;
import org.dromara.hutool.crypto.digest.MD5; import org.dromara.hutool.crypto.digest.MD5;
import org.dromara.hutool.crypto.provider.GlobalProviderFactory;
import org.dromara.hutool.crypto.symmetric.AES; import org.dromara.hutool.crypto.symmetric.AES;
import org.dromara.hutool.crypto.symmetric.DES; import org.dromara.hutool.crypto.symmetric.DES;
import org.dromara.hutool.crypto.symmetric.DESede; import org.dromara.hutool.crypto.symmetric.DESede;
@ -536,7 +537,7 @@ public class SecureUtil {
* @since 4.5.2 * @since 4.5.2
*/ */
public static Cipher createCipher(final String algorithm) { public static Cipher createCipher(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final Cipher cipher; final Cipher cipher;
try { try {
@ -556,7 +557,7 @@ public class SecureUtil {
* @since 4.5.2 * @since 4.5.2
*/ */
public static MessageDigest createMessageDigest(final String algorithm) { public static MessageDigest createMessageDigest(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final MessageDigest messageDigest; final MessageDigest messageDigest;
try { try {
@ -576,7 +577,7 @@ public class SecureUtil {
* @since 4.5.13 * @since 4.5.13
*/ */
public static Mac createMac(final String algorithm) { public static Mac createMac(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final Mac mac; final Mac mac;
try { try {
@ -604,7 +605,7 @@ public class SecureUtil {
* @since 4.5.2 * @since 4.5.2
*/ */
public static void disableBouncyCastle() { public static void disableBouncyCastle() {
GlobalBouncyCastleProvider.setUseBouncyCastle(false); GlobalProviderFactory.setUseCustomProvider(false);
} }
/** /**

View File

@ -19,6 +19,7 @@ import org.dromara.hutool.crypto.asymmetric.Sign;
import org.dromara.hutool.crypto.asymmetric.SignAlgorithm; import org.dromara.hutool.crypto.asymmetric.SignAlgorithm;
import org.dromara.hutool.crypto.digest.DigestAlgorithm; import org.dromara.hutool.crypto.digest.DigestAlgorithm;
import org.dromara.hutool.crypto.digest.Digester; import org.dromara.hutool.crypto.digest.Digester;
import org.dromara.hutool.crypto.provider.GlobalProviderFactory;
import org.dromara.hutool.crypto.symmetric.SymmetricCrypto; import org.dromara.hutool.crypto.symmetric.SymmetricCrypto;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -59,7 +60,7 @@ public class SignUtil {
* @since 5.7.0 * @since 5.7.0
*/ */
public static Signature createSignature(final String algorithm) { public static Signature createSignature(final String algorithm) {
final Provider provider = GlobalBouncyCastleProvider.INSTANCE.getProvider(); final Provider provider = GlobalProviderFactory.getProvider();
final Signature signature; final Signature signature;
try { try {

View File

@ -13,7 +13,7 @@
package org.dromara.hutool.crypto.asymmetric; package org.dromara.hutool.crypto.asymmetric;
import org.dromara.hutool.crypto.CryptoException; import org.dromara.hutool.crypto.CryptoException;
import org.dromara.hutool.crypto.GlobalBouncyCastleProvider; import org.dromara.hutool.crypto.provider.GlobalProviderFactory;
import org.dromara.hutool.crypto.KeyUtil; import org.dromara.hutool.crypto.KeyUtil;
import java.math.BigInteger; import java.math.BigInteger;
@ -169,7 +169,7 @@ public class RSA extends AsymmetricCrypto {
@Override @Override
public byte[] encrypt(final byte[] data, final KeyType keyType) { public byte[] encrypt(final byte[] data, final KeyType keyType) {
// 在非使用BC库情况下blockSize使用默认的算法 // 在非使用BC库情况下blockSize使用默认的算法
if (this.encryptBlockSize < 0 && null == GlobalBouncyCastleProvider.INSTANCE.getProvider()) { if (this.encryptBlockSize < 0 && null == GlobalProviderFactory.getProvider()) {
// 加密数据长度 <= 模长-11 // 加密数据长度 <= 模长-11
this.encryptBlockSize = ((RSAKey) getKeyByType(keyType)).getModulus().bitLength() / 8 - 11; this.encryptBlockSize = ((RSAKey) getKeyByType(keyType)).getModulus().bitLength() / 8 - 11;
} }
@ -179,7 +179,7 @@ public class RSA extends AsymmetricCrypto {
@Override @Override
public byte[] decrypt(final byte[] bytes, final KeyType keyType) { public byte[] decrypt(final byte[] bytes, final KeyType keyType) {
// 在非使用BC库情况下blockSize使用默认的算法 // 在非使用BC库情况下blockSize使用默认的算法
if (this.decryptBlockSize < 0 && null == GlobalBouncyCastleProvider.INSTANCE.getProvider()) { if (this.decryptBlockSize < 0 && null == GlobalProviderFactory.getProvider()) {
// 加密数据长度 <= 模长-11 // 加密数据长度 <= 模长-11
this.decryptBlockSize = ((RSAKey) getKeyByType(keyType)).getModulus().bitLength() / 8; this.decryptBlockSize = ((RSAKey) getKeyByType(keyType)).getModulus().bitLength() / 8;
} }

View File

@ -14,9 +14,9 @@ package org.dromara.hutool.crypto.asymmetric;
import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.codec.HexUtil; import org.dromara.hutool.core.codec.HexUtil;
import org.dromara.hutool.crypto.BCUtil; import org.dromara.hutool.crypto.bc.BCUtil;
import org.dromara.hutool.crypto.CryptoException; import org.dromara.hutool.crypto.CryptoException;
import org.dromara.hutool.crypto.ECKeyUtil; import org.dromara.hutool.crypto.bc.ECKeyUtil;
import org.dromara.hutool.crypto.SecureUtil; import org.dromara.hutool.crypto.SecureUtil;
import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Digest;
@ -33,7 +33,7 @@ import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.crypto.signers.StandardDSAEncoding;
import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.Hex;
import org.dromara.hutool.crypto.SmUtil; import org.dromara.hutool.crypto.bc.SmUtil;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.PrivateKey; import java.security.PrivateKey;

View File

@ -10,7 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.stream.FastByteArrayOutputStream; import org.dromara.hutool.core.io.stream.FastByteArrayOutputStream;
import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IORuntimeException;
@ -23,6 +23,7 @@ import org.bouncycastle.asn1.BERSequence;
import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DLSequence;
import org.bouncycastle.asn1.util.ASN1Dump; import org.bouncycastle.asn1.util.ASN1Dump;
import org.dromara.hutool.crypto.CryptoException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;

View File

@ -10,7 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IORuntimeException;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
@ -27,6 +27,7 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECCurve;
import org.dromara.hutool.crypto.*;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;

View File

@ -10,7 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IORuntimeException;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
@ -28,6 +28,9 @@ import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.FixedPointCombMultiplier; import org.bouncycastle.math.ec.FixedPointCombMultiplier;
import org.bouncycastle.util.BigIntegers; import org.bouncycastle.util.BigIntegers;
import org.dromara.hutool.crypto.CryptoException;
import org.dromara.hutool.crypto.KeyUtil;
import org.dromara.hutool.crypto.SecureUtil;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;

View File

@ -10,7 +10,7 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IORuntimeException;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
@ -30,6 +30,8 @@ import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.bouncycastle.pkcs.PKCSException; import org.bouncycastle.pkcs.PKCSException;
import org.dromara.hutool.crypto.CryptoException;
import org.dromara.hutool.crypto.provider.GlobalProviderFactory;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -48,7 +50,8 @@ import java.security.PublicKey;
*/ */
public class OpensslKeyUtil { public class OpensslKeyUtil {
private static final JcaPEMKeyConverter pemKeyConverter = new JcaPEMKeyConverter().setProvider(GlobalBouncyCastleProvider.INSTANCE.getProvider()); private static final JcaPEMKeyConverter pemKeyConverter =
new JcaPEMKeyConverter().setProvider(GlobalProviderFactory.getProvider());
/** /**
* 转换{@link PrivateKeyInfo}{@link PrivateKey} * 转换{@link PrivateKeyInfo}{@link PrivateKey}
@ -106,7 +109,8 @@ public class OpensslKeyUtil {
public static PrivateKeyInfo decrypt(final PKCS8EncryptedPrivateKeyInfo pkcs8Info, final char[] password) throws CryptoException { public static PrivateKeyInfo decrypt(final PKCS8EncryptedPrivateKeyInfo pkcs8Info, final char[] password) throws CryptoException {
final InputDecryptorProvider decryptProvider; final InputDecryptorProvider decryptProvider;
try { try {
decryptProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder().setProvider(GlobalBouncyCastleProvider.INSTANCE.getProvider()).build(password); decryptProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder()
.setProvider(GlobalProviderFactory.getProvider()).build(password);
return pkcs8Info.decryptPrivateKeyInfo(decryptProvider); return pkcs8Info.decryptPrivateKeyInfo(decryptProvider);
} catch (final OperatorCreationException | PKCSException e) { } catch (final OperatorCreationException | PKCSException e) {
throw new CryptoException(e); throw new CryptoException(e);
@ -124,7 +128,8 @@ public class OpensslKeyUtil {
public static PEMKeyPair decrypt(final PEMEncryptedKeyPair pemEncryptedKeyPair, final char[] password) throws IORuntimeException { public static PEMKeyPair decrypt(final PEMEncryptedKeyPair pemEncryptedKeyPair, final char[] password) throws IORuntimeException {
final PEMDecryptorProvider decryptProvider; final PEMDecryptorProvider decryptProvider;
try { try {
decryptProvider = new JcePEMDecryptorProviderBuilder().setProvider(GlobalBouncyCastleProvider.INSTANCE.getProvider()).build(password); decryptProvider = new JcePEMDecryptorProviderBuilder()
.setProvider(GlobalProviderFactory.getProvider()).build(password);
return pemEncryptedKeyPair.decryptKeyPair(decryptProvider); return pemEncryptedKeyPair.decryptKeyPair(decryptProvider);
} catch (final IOException e) { } catch (final IOException e) {
throw new IORuntimeException(e); throw new IORuntimeException(e);

View File

@ -10,22 +10,18 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemObjectGenerator; import org.bouncycastle.util.io.pem.PemObjectGenerator;
import org.bouncycastle.util.io.pem.PemReader; import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter; import org.bouncycastle.util.io.pem.PemWriter;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.crypto.KeyUtil;
import java.io.IOException; import java.io.*;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.security.Key; import java.security.Key;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
@ -96,7 +92,7 @@ public class PemUtil {
try { try {
// 尝试DER // 尝试DER
return KeyUtil.generatePublicKey("EC", object.getContent()); return KeyUtil.generatePublicKey("EC", object.getContent());
} catch (Exception e) { } catch (final Exception ignore) {
// 尝试PKCS#1 // 尝试PKCS#1
return KeyUtil.generatePublicKey("EC", ECKeyUtil.createOpenSSHPublicKeySpec(object.getContent())); return KeyUtil.generatePublicKey("EC", ECKeyUtil.createOpenSSHPublicKeySpec(object.getContent()));
} }

View File

@ -10,18 +10,8 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.crypto.asymmetric.SM2;
import org.dromara.hutool.crypto.digest.HMac;
import org.dromara.hutool.crypto.digest.HmacAlgorithm;
import org.dromara.hutool.crypto.digest.SM3;
import org.dromara.hutool.crypto.digest.mac.BCHMacEngine;
import org.dromara.hutool.crypto.digest.mac.MacEngine;
import org.dromara.hutool.crypto.symmetric.SM4;
import org.dromara.hutool.crypto.symmetric.SymmetricCrypto;
import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.crypto.digests.SM3Digest;
@ -31,6 +21,17 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.signers.StandardDSAEncoding; import org.bouncycastle.crypto.signers.StandardDSAEncoding;
import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.encoders.Hex;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.crypto.CryptoException;
import org.dromara.hutool.crypto.asymmetric.SM2;
import org.dromara.hutool.crypto.digest.HMac;
import org.dromara.hutool.crypto.digest.HmacAlgorithm;
import org.dromara.hutool.crypto.digest.SM3;
import org.dromara.hutool.crypto.digest.mac.BCHMacEngine;
import org.dromara.hutool.crypto.digest.mac.MacEngine;
import org.dromara.hutool.crypto.symmetric.SM4;
import org.dromara.hutool.crypto.symmetric.SymmetricCrypto;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* BouncyCastle库相关工具封装
*
* @author looly
* @since 6.0.0
*/
package org.dromara.hutool.crypto.bc;

View File

@ -12,7 +12,7 @@
package org.dromara.hutool.crypto.digest.mac; package org.dromara.hutool.crypto.digest.mac;
import org.dromara.hutool.crypto.SmUtil; import org.dromara.hutool.crypto.bc.SmUtil;
import org.dromara.hutool.crypto.digest.HmacAlgorithm; import org.dromara.hutool.crypto.digest.HmacAlgorithm;
import java.security.Key; import java.security.Key;

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.provider;
import java.security.Provider;
/**
* {@link org.bouncycastle.jce.provider.BouncyCastleProvider} 工厂类
*
* @author looly
* @since 6.0.0
*/
public class BouncyCastleProviderFactory implements ProviderFactory {
@Override
public Provider create() {
return new org.bouncycastle.jce.provider.BouncyCastleProvider();
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.provider;
import org.dromara.hutool.core.util.ServiceLoaderUtil;
import org.dromara.hutool.crypto.SecureUtil;
import java.security.Provider;
/**
* 全局单例的{@link Provider}对象<br>
* 在此类加载时通过SPI方式查找用户引入的加密库查找对应的{@link Provider}实现然后全局创建唯一的{@link Provider}对象<br>
* 用户依旧可以通过{@link #setUseCustomProvider(boolean)} 方法选择是否使用自定义的Provider
*
* @author looly
*/
public class GlobalProviderFactory {
private static boolean useCustomProvider = true;
private static final Provider provider = _createProvider();
/**
* 获取{@link Provider}
*
* @return {@link Provider}
*/
public static Provider getProvider() {
return useCustomProvider ? provider : null;
}
/**
* 设置是否使用自定义的{@link Provider}<br>
* 如果设置为false表示使用JDK默认的Provider
*
* @param isUseCustomProvider 是否使用自定义{@link Provider}
*/
public static void setUseCustomProvider(final boolean isUseCustomProvider) {
useCustomProvider = isUseCustomProvider;
}
/**
* 通过SPI方式创建{@link Provider}无提供的返回{@code null}
*
* @return {@link Provider} or {@code null}
*/
private static Provider _createProvider() {
final ProviderFactory factory = ServiceLoaderUtil.loadFirstAvailable(ProviderFactory.class);
if (null == factory) {
return null;
}
final Provider provider = factory.create();
// issue#2631@Github
SecureUtil.addProvider(provider);
return provider;
}
}

View File

@ -10,32 +10,24 @@
* See the Mulan PSL v2 for more details. * See the Mulan PSL v2 for more details.
*/ */
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto.provider;
import java.security.Provider; import java.security.Provider;
/** /**
* Provider对象生产工厂类 * Provider对象生产工厂类<br>
* * 通过SPI方式加载可用的{@link ProviderFactory}并创建对应的{@link Provider}<br>
* <pre> * spi定义在META-INF/services/org.dromara.hutool.crypto.provider.ProviderFactory
* 1. 调用{@link #createBouncyCastleProvider()} 用于新建一个org.bouncycastle.jce.provider.BouncyCastleProvider对象
* </pre>
* *
* @author looly * @author looly
* @since 4.2.1 * @since 6.0.0
*/ */
public class ProviderFactory { public interface ProviderFactory {
/** /**
* 创建Bouncy Castle 提供者<br> * 创建{@link Provider}
* 如果用户未引入bouncycastle库则此方法抛出{@link NoClassDefFoundError} 异常
* *
* @return {@link Provider} * @return {@link Provider}
*/ */
public static Provider createBouncyCastleProvider() { Provider create();
final org.bouncycastle.jce.provider.BouncyCastleProvider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
// issue#2631@Github
SecureUtil.addProvider(provider);
return provider;
}
} }

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* {@link java.security.Provider}相关封装通过SPI机制提供灵活的Provider注入<br>
* spi定义在META-INF/services/org.dromara.hutool.crypto.provider.ProviderFactory
*
* <pre>
* GlobalProviderFactory单例持有Provider
* ^
* create
* ProviderFactory
* |
* BouncyCastleProviderFactory
* </pre>
*
* @author looly
* @since 6.0.0
*/
package org.dromara.hutool.crypto.provider;

View File

@ -27,6 +27,9 @@ import javax.crypto.spec.IvParameterSpec;
public class ChaCha20 extends SymmetricCrypto { public class ChaCha20 extends SymmetricCrypto {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 算法名称ChaCha20
*/
public static final String ALGORITHM_NAME = "ChaCha20"; public static final String ALGORITHM_NAME = "ChaCha20";
/** /**

View File

@ -31,7 +31,7 @@ import javax.crypto.spec.IvParameterSpec;
public class DES extends SymmetricCrypto { public class DES extends SymmetricCrypto {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// ------------------------------------------------------------------------- Constrctor start // region ----- Constructor
/** /**
* 构造默认DES/ECB/PKCS5Padding使用随机密钥 * 构造默认DES/ECB/PKCS5Padding使用随机密钥
*/ */
@ -162,5 +162,5 @@ public class DES extends SymmetricCrypto {
public DES(final String mode, final String padding, final SecretKey key, final IvParameterSpec iv) { public DES(final String mode, final String padding, final SecretKey key, final IvParameterSpec iv) {
super(StrUtil.format("DES/{}/{}", mode, padding), key, iv); super(StrUtil.format("DES/{}/{}", mode, padding), key, iv);
} }
// ------------------------------------------------------------------------- Constrctor end // endregion
} }

View File

@ -35,12 +35,16 @@ import javax.crypto.spec.IvParameterSpec;
* @author Looly * @author Looly
* @since 4.6.8 * @since 4.6.8
*/ */
public class SM4 extends SymmetricCrypto{ public class SM4 extends SymmetricCrypto {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 算法名称SM4
*/
public static final String ALGORITHM_NAME = "SM4"; public static final String ALGORITHM_NAME = "SM4";
//------------------------------------------------------------------------- Constrctor start // region ----- Constructor
/** /**
* 构造使用随机密钥 * 构造使用随机密钥
*/ */
@ -182,5 +186,5 @@ public class SM4 extends SymmetricCrypto{
public SM4(final String mode, final String padding, final SecretKey key, final IvParameterSpec iv) { public SM4(final String mode, final String padding, final SecretKey key, final IvParameterSpec iv) {
super(StrUtil.format("SM4/{}/{}", mode, padding), key, iv); super(StrUtil.format("SM4/{}/{}", mode, padding), key, iv);
} }
//------------------------------------------------------------------------- Constrctor end // endregion
} }

View File

@ -17,27 +17,50 @@ package org.dromara.hutool.crypto.symmetric;
* see: https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyGenerator * see: https://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#KeyGenerator
* *
* @author Looly * @author Looly
*
*/ */
public enum SymmetricAlgorithm { public enum SymmetricAlgorithm {
/** 默认的AES加密方式AES/ECB/PKCS5Padding */ /**
* 默认的AES加密方式AES/ECB/PKCS5Padding
*/
AES("AES"), AES("AES"),
/**
* ARCFOUR
*/
ARCFOUR("ARCFOUR"), ARCFOUR("ARCFOUR"),
/**
* Blowfish
*/
Blowfish("Blowfish"), Blowfish("Blowfish"),
/** 默认的DES加密方式DES/ECB/PKCS5Padding */ /**
* 默认的DES加密方式DES/ECB/PKCS5Padding
*/
DES("DES"), DES("DES"),
/** 3DES算法默认实现为DESede/ECB/PKCS5Padding */ /**
* 3DES算法默认实现为DESede/ECB/PKCS5Padding
*/
DESede("DESede"), DESede("DESede"),
/**
* RC2
*/
RC2("RC2"), RC2("RC2"),
/**
*PBEWithMD5AndDES
*/
PBEWithMD5AndDES("PBEWithMD5AndDES"), PBEWithMD5AndDES("PBEWithMD5AndDES"),
/**
* PBEWithSHA1AndDESede
*/
PBEWithSHA1AndDESede("PBEWithSHA1AndDESede"), PBEWithSHA1AndDESede("PBEWithSHA1AndDESede"),
/**
* PBEWithSHA1AndRC2_40
*/
PBEWithSHA1AndRC2_40("PBEWithSHA1AndRC2_40"); PBEWithSHA1AndRC2_40("PBEWithSHA1AndRC2_40");
private final String value; private final String value;
/** /**
* 构造 * 构造
*
* @param value 算法的字符串表示区分大小写 * @param value 算法的字符串表示区分大小写
*/ */
SymmetricAlgorithm(final String value) { SymmetricAlgorithm(final String value) {
@ -46,6 +69,7 @@ public enum SymmetricAlgorithm {
/** /**
* 获得算法的字符串表示形式 * 获得算法的字符串表示形式
*
* @return 算法字符串 * @return 算法字符串
*/ */
public String getValue() { public String getValue() {

View File

@ -57,7 +57,13 @@ public class ZUC extends SymmetricCrypto {
* @author looly * @author looly
*/ */
public enum ZUCAlgorithm { public enum ZUCAlgorithm {
/**
* ZUC-128
*/
ZUC_128("ZUC-128"), ZUC_128("ZUC-128"),
/**
* ZUC-256
*/
ZUC_256("ZUC-256"); ZUC_256("ZUC-256");
private final String value; private final String value;

View File

@ -0,0 +1 @@
org.dromara.hutool.crypto.provider.BouncyCastleProviderFactory

View File

@ -1,5 +1,6 @@
package org.dromara.hutool.crypto; package org.dromara.hutool.crypto;
import org.dromara.hutool.crypto.provider.GlobalProviderFactory;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -17,7 +18,7 @@ public class KeyUtilTest {
@Disabled @Disabled
public void generateKeyPairTest() { public void generateKeyPairTest() {
Assertions.assertThrows(CryptoException.class, ()->{ Assertions.assertThrows(CryptoException.class, ()->{
GlobalBouncyCastleProvider.setUseBouncyCastle(false); GlobalProviderFactory.setUseCustomProvider(false);
final KeyPair pair = KeyUtil.generateKeyPair("SM2"); final KeyPair pair = KeyUtil.generateKeyPair("SM2");
Assertions.assertNotNull(pair); Assertions.assertNotNull(pair);
}); });

View File

@ -5,6 +5,7 @@ import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.crypto.asymmetric.Sign; import org.dromara.hutool.crypto.asymmetric.Sign;
import org.dromara.hutool.crypto.asymmetric.SignAlgorithm; import org.dromara.hutool.crypto.asymmetric.SignAlgorithm;
import org.dromara.hutool.crypto.bc.PemUtil;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;

View File

@ -5,10 +5,10 @@ import org.dromara.hutool.core.codec.binary.Base64;
import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.StrUtil;
import org.dromara.hutool.core.util.ByteUtil; import org.dromara.hutool.core.util.ByteUtil;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.crypto.ECKeyUtil; import org.dromara.hutool.crypto.bc.ECKeyUtil;
import org.dromara.hutool.crypto.KeyUtil; import org.dromara.hutool.crypto.KeyUtil;
import org.dromara.hutool.crypto.SecureUtil; import org.dromara.hutool.crypto.SecureUtil;
import org.dromara.hutool.crypto.SmUtil; import org.dromara.hutool.crypto.bc.SmUtil;
import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec; import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;

View File

@ -1,4 +1,16 @@
package org.dromara.hutool.crypto; /*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.bc;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters;

View File

@ -1,4 +1,16 @@
package org.dromara.hutool.crypto; /*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.resource.ResourceUtil; import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.util.ByteUtil; import org.dromara.hutool.core.util.ByteUtil;

View File

@ -1,4 +1,16 @@
package org.dromara.hutool.crypto; /*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.io.file.FileUtil; import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.io.resource.ResourceUtil; import org.dromara.hutool.core.io.resource.ResourceUtil;

View File

@ -1,6 +1,22 @@
package org.dromara.hutool.crypto; /*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.bc;
import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.CharsetUtil;
import org.dromara.hutool.crypto.KeyUtil;
import org.dromara.hutool.crypto.Mode;
import org.dromara.hutool.crypto.Padding;
import org.dromara.hutool.crypto.bc.SmUtil;
import org.dromara.hutool.crypto.digest.HMac; import org.dromara.hutool.crypto.digest.HMac;
import org.dromara.hutool.crypto.symmetric.SM4; import org.dromara.hutool.crypto.symmetric.SM4;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.crypto.provider;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.security.Provider;
/**
* 单元测试只针对bouncycastle引入有效
*/
public class GlobalProviderFactoryTest {
@Test
void getProviderTest() {
final Provider provider = GlobalProviderFactory.getProvider();
Assertions.assertNotNull(provider);
Assertions.assertEquals(
"org.bouncycastle.jce.provider.BouncyCastleProvider",
provider.getClass().getName());
}
}

View File

@ -21,7 +21,7 @@ import net.sf.cglib.proxy.Enhancer;
* *
* @author looly * @author looly
*/ */
public class CglibProxyFactory extends ProxyFactory { public class CglibProxyFactory implements ProxyFactory {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override

View File

@ -21,7 +21,7 @@ import org.dromara.hutool.extra.aop.interceptor.JdkInterceptor;
* *
* @author looly * @author looly
*/ */
public class JdkProxyFactory extends ProxyFactory { public class JdkProxyFactory implements ProxyFactory {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override

View File

@ -24,31 +24,7 @@ import java.io.Serializable;
* *
* @author looly * @author looly
*/ */
public abstract class ProxyFactory implements Serializable { public interface ProxyFactory extends Serializable {
private static final long serialVersionUID = 1L;
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspectClass 切面实现类自动实例化
* @return 代理对象
* @since 5.3.1
*/
public <T> T proxy(final T target, final Class<? extends Aspect> aspectClass) {
return proxy(target, ConstructorUtil.newInstanceIfPossible(aspectClass));
}
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
public abstract <T> T proxy(T target, Aspect aspect);
/** /**
* 根据用户引入Cglib与否自动创建代理对象 * 根据用户引入Cglib与否自动创建代理对象
@ -58,7 +34,7 @@ public abstract class ProxyFactory implements Serializable {
* @param aspectClass 切面对象类 * @param aspectClass 切面对象类
* @return 代理对象 * @return 代理对象
*/ */
public static <T> T createProxy(final T target, final Class<? extends Aspect> aspectClass) { static <T> T createProxy(final T target, final Class<? extends Aspect> aspectClass) {
return createProxy(target, ConstructorUtil.newInstance(aspectClass)); return createProxy(target, ConstructorUtil.newInstance(aspectClass));
} }
@ -70,7 +46,7 @@ public abstract class ProxyFactory implements Serializable {
* @param aspect 切面实现 * @param aspect 切面实现
* @return 代理对象 * @return 代理对象
*/ */
public static <T> T createProxy(final T target, final Aspect aspect) { static <T> T createProxy(final T target, final Aspect aspect) {
return of().proxy(target, aspect); return of().proxy(target, aspect);
} }
@ -79,7 +55,30 @@ public abstract class ProxyFactory implements Serializable {
* *
* @return 代理工厂 * @return 代理工厂
*/ */
public static ProxyFactory of() { static ProxyFactory of() {
return ServiceLoaderUtil.loadFirstAvailable(ProxyFactory.class); return ServiceLoaderUtil.loadFirstAvailable(ProxyFactory.class);
} }
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspectClass 切面实现类自动实例化
* @return 代理对象
* @since 5.3.1
*/
default <T> T proxy(final T target, final Class<? extends Aspect> aspectClass) {
return proxy(target, ConstructorUtil.newInstanceIfPossible(aspectClass));
}
/**
* 创建代理
*
* @param <T> 代理对象类型
* @param target 被代理对象
* @param aspect 切面实现
* @return 代理对象
*/
<T> T proxy(T target, Aspect aspect);
} }

View File

@ -22,7 +22,7 @@ import org.springframework.cglib.proxy.Enhancer;
* @author looly * @author looly
* *
*/ */
public class SpringCglibProxyFactory extends ProxyFactory{ public class SpringCglibProxyFactory implements ProxyFactory{
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Override @Override