main
13009 2024-02-20 14:32:37 +08:00
parent 93ac3cf32c
commit cb00660a74
25 changed files with 147 additions and 68 deletions

View File

@ -10,6 +10,8 @@ import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Provider;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
@ -18,21 +20,34 @@ import static java.util.Objects.requireNonNull;
* @date 2024/2/2
*/
public abstract class AbstractPrivacyDecryptor implements PrivacyDecryptor {
private final PrivateKey privateKey;
private final Cipher cipher;
protected final String transformation;
protected final PrivateKey privateKey;
protected final Provider provider;
/**
*
*
* @param transform 使
* @param privateKey 使
* @param transformation 使
* @param privateKey 使
* @param provider
*/
protected AbstractPrivacyDecryptor(String transform, PrivateKey privateKey) {
protected AbstractPrivacyDecryptor(String transformation, PrivateKey privateKey, Provider provider) {
this.transformation = requireNonNull(transformation);
this.privateKey = requireNonNull(privateKey);
this.provider = provider;
}
/**
*
*
* @return Cipher
*/
private Cipher getCipher() {
try {
cipher = Cipher.getInstance(transform);
return Objects.isNull(provider) ? Cipher.getInstance(transformation)
: Cipher.getInstance(transformation, provider);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalArgumentException("The current Java environment does not support " + transform, e);
throw new IllegalArgumentException("The current Java environment does not support " + transformation, e);
}
}
@ -46,12 +61,13 @@ public abstract class AbstractPrivacyDecryptor implements PrivacyDecryptor {
public String decrypt(String ciphertext) {
requireNonNull(ciphertext);
try {
Cipher cipher = getCipher();
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return Strings.toStr(cipher.doFinal(Base64.decode(ciphertext)));
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的私钥", e);
} catch (BadPaddingException | IllegalBlockSizeException e) {
throw new IllegalArgumentException(String.format("[%s]解密失败", cipher.getAlgorithm()), e);
throw new IllegalArgumentException(String.format("[%s]解密失败", transformation), e);
}
}

View File

@ -9,7 +9,9 @@ import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.PublicKey;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
@ -18,21 +20,34 @@ import static java.util.Objects.requireNonNull;
* @date 2024/2/2
*/
public abstract class AbstractPrivacyEncryptor implements PrivacyEncryptor {
private final PublicKey publicKey;
private final Cipher cipher;
protected final String transformation;
protected final PublicKey publicKey;
protected final Provider provider;
/**
*
*
* @param transform 使
* @param publicKey 使
* @param transformation 使
* @param publicKey 使
* @param provider
*/
protected AbstractPrivacyEncryptor(String transform, PublicKey publicKey) {
protected AbstractPrivacyEncryptor(String transformation, PublicKey publicKey, Provider provider) {
this.transformation = requireNonNull(transformation);
this.publicKey = requireNonNull(publicKey);
this.provider = provider;
}
/**
*
*
* @return Cipher
*/
private Cipher getCipher() {
try {
cipher = Cipher.getInstance(transform);
return Objects.isNull(provider) ? Cipher.getInstance(transformation)
: Cipher.getInstance(transformation, provider);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalArgumentException("The current Java environment does not support " + transform, e);
throw new IllegalArgumentException("The current Java environment does not support " + transformation, e);
}
}
@ -45,13 +60,15 @@ public abstract class AbstractPrivacyEncryptor implements PrivacyEncryptor {
@Override
public String encrypt(String plaintext) {
requireNonNull(plaintext);
try {
Cipher cipher = getCipher();
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeStr(cipher.doFinal(Strings.toBytes(plaintext)));
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("无效的公钥", e);
} catch (BadPaddingException | IllegalBlockSizeException e) {
throw new IllegalArgumentException(String.format("[%s]算法加密失败", cipher.getAlgorithm()), e);
throw new IllegalArgumentException(String.format("[%s]算法加密失败", transformation), e);
}
}

View File

@ -5,29 +5,50 @@ import com.czcb.scfs.api.core.exception.EncryptException;
import com.czcb.scfs.api.core.util.Base64;
import com.czcb.scfs.api.core.util.Strings;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.util.Objects;
/**
*
*
* @author wangwei
* @date 2024/2/2
*/
public abstract class AbstractSecretCipher implements SecretCipher {
private final String algorithm;
private final String transformation;
private final int keyLengthBit;
protected final String algorithm;
protected final String transformation;
protected final Provider provider;
protected final int keyLengthBit;
protected AbstractSecretCipher(String algorithm, String transformation, int keyLengthBit) {
protected AbstractSecretCipher(String algorithm, String transformation, Provider provider, int keyLengthBit) {
this.algorithm = algorithm;
this.transformation = transformation;
this.provider = provider;
this.keyLengthBit = keyLengthBit;
}
/**
*
*
* @return Cipher
*/
private Cipher getCipher() {
try {
return Objects.isNull(provider) ? Cipher.getInstance(transformation)
: Cipher.getInstance(transformation, provider);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
throw new IllegalArgumentException("The current Java environment does not support " + transformation, e);
}
}
/**
*
*
@ -37,8 +58,8 @@ public abstract class AbstractSecretCipher implements SecretCipher {
@Override
public String encrypt(byte[] secretKey, byte[] plaintext) {
try {
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(transformation);
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE,
Cipher cipher = getCipher();
cipher.init(Cipher.ENCRYPT_MODE,
new SecretKeySpec(secretKey, algorithm),
new GCMParameterSpec(keyLengthBit, secretKey));
return Base64.encodeStr(cipher.doFinal(plaintext));
@ -56,15 +77,12 @@ public abstract class AbstractSecretCipher implements SecretCipher {
@Override
public String decrypt(byte[] secretKey, byte[] ciphertext) {
try {
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(transformation);
cipher.init(javax.crypto.Cipher.DECRYPT_MODE,
Cipher cipher = getCipher();
cipher.init(Cipher.DECRYPT_MODE,
new SecretKeySpec(secretKey, algorithm),
new GCMParameterSpec(keyLengthBit, secretKey));
return Strings.toStr(cipher.doFinal(Base64.decode(ciphertext)));
} catch (InvalidKeyException
| InvalidAlgorithmParameterException
| NoSuchAlgorithmException
| NoSuchPaddingException e) {
} catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
throw new IllegalArgumentException(e);
} catch (Exception e) {
throw new DecryptException("解密异常", e);

View File

@ -4,10 +4,8 @@ import com.czcb.scfs.api.core.exception.SignException;
import com.czcb.scfs.api.core.util.Base64;
import com.czcb.scfs.api.core.util.Strings;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.*;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
@ -17,9 +15,10 @@ import static java.util.Objects.requireNonNull;
* @date 2024/2/2
*/
public abstract class AbstractSigner implements Signer {
private final String algorithm;
private final String algorithmName;
private final PrivateKey privateKey;
protected final String algorithm;
protected final String algorithmName;
protected final PrivateKey privateKey;
protected final Provider provider;
/**
* AbstractSigner
@ -28,10 +27,20 @@ public abstract class AbstractSigner implements Signer {
* @param algorithmName SignatureSHA256withRSA
* @param privateKey API
*/
protected AbstractSigner(String algorithm, String algorithmName, PrivateKey privateKey) {
protected AbstractSigner(String algorithm, String algorithmName, PrivateKey privateKey, Provider provider) {
this.algorithm = requireNonNull(algorithm);
this.algorithmName = requireNonNull(algorithmName);
this.privateKey = requireNonNull(privateKey);
this.provider = provider;
}
private java.security.Signature getSignature() {
try {
return Objects.isNull(provider) ? java.security.Signature.getInstance(algorithmName)
: java.security.Signature.getInstance(algorithmName, provider);
} catch (NoSuchAlgorithmException e) {
throw new UnsupportedOperationException("The current Java environment does not support " + algorithmName, e);
}
}
@Override
@ -39,12 +48,10 @@ public abstract class AbstractSigner implements Signer {
requireNonNull(message);
try {
java.security.Signature signature = java.security.Signature.getInstance(algorithmName);
java.security.Signature signature = getSignature();
signature.initSign(privateKey);
signature.update(Strings.toBytes(message));
return new SignatureResult(Base64.encodeStr(signature.sign()));
} catch (NoSuchAlgorithmException e) {
throw new UnsupportedOperationException("The current Java environment does not support " + algorithmName, e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException(algorithm + " signature uses an illegal privateKey.", e);
} catch (SignatureException e) {

View File

@ -5,11 +5,10 @@ import com.czcb.scfs.api.core.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.*;
import java.security.cert.X509Certificate;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
@ -20,22 +19,33 @@ import static java.util.Objects.requireNonNull;
public abstract class AbstractVerifier implements Verifier {
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected final CertificateProvider certificateProvider;
protected final String algorithmName;
protected final String algorithm;
protected final Provider provider;
/**
* AbstractVerifier
*
* @param algorithmName Signature
* @param algorithm Signature
* @param certificateProvider 使
*/
protected AbstractVerifier(String algorithmName, CertificateProvider certificateProvider) {
this.algorithmName = requireNonNull(algorithmName);
protected AbstractVerifier(String algorithm, CertificateProvider certificateProvider, Provider provider) {
this.algorithm = requireNonNull(algorithm);
this.certificateProvider = requireNonNull(certificateProvider);
this.provider = provider;
}
private java.security.Signature getSignature() {
try {
return Objects.isNull(provider) ? java.security.Signature.getInstance(algorithm)
: java.security.Signature.getInstance(algorithm, provider);
} catch (NoSuchAlgorithmException e) {
throw new UnsupportedOperationException("The current Java environment does not support " + algorithm, e);
}
}
protected boolean verify(X509Certificate certificate, String message, String signature) {
try {
Signature sign = Signature.getInstance(algorithmName);
Signature sign = getSignature();
sign.initVerify(certificate);
sign.update(Strings.toBytes(message));
return sign.verify(Base64.decode(signature));
@ -43,8 +53,6 @@ public abstract class AbstractVerifier implements Verifier {
return false;
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("verify uses an illegal certificate.", e);
} catch (NoSuchAlgorithmException e) {
throw new UnsupportedOperationException("不支持的签名算法:" + algorithmName, e);
}
}

View File

@ -6,14 +6,13 @@ import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
*
*/
public class CertificateValidity {
public X509Certificate getLongestCertificate(ConcurrentHashMap<BigInteger, X509Certificate> certificates) {
public X509Certificate getLongestCertificate(Map<BigInteger, X509Certificate> certificates) {
if (certificates == null || certificates.isEmpty()) {
return null;
}

View File

@ -11,6 +11,6 @@ public class TestPrivacyDecryptor extends AbstractPrivacyDecryptor {
* @param privateKey 使
*/
protected TestPrivacyDecryptor(PrivateKey privateKey) {
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", privateKey);
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", privateKey, null);
}
}

View File

@ -11,6 +11,6 @@ public class TestPrivacyEncryptor extends AbstractPrivacyEncryptor {
* @param publicKey 使
*/
protected TestPrivacyEncryptor(PublicKey publicKey) {
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", publicKey);
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", publicKey, null);
}
}

View File

@ -5,6 +5,6 @@ import com.czcb.scfs.api.core.cipher.AbstractSecretCipher;
public class TestSecretCipher extends AbstractSecretCipher {
protected TestSecretCipher() {
super("AES", "AES/GCM/NoPadding", 128);
super("AES", "AES/GCM/NoPadding", null, 128);
}
}

View File

@ -14,6 +14,6 @@ public class TestSigner extends AbstractSigner {
* @param privateKey API
*/
protected TestSigner(PrivateKey privateKey) {
super("SHA256-WITH-RSA", "SHA256withRSA", privateKey);
super("SHA256withRSA", "SHA256withRSA", privateKey, null);
}
}

View File

@ -12,6 +12,6 @@ public class TestVerifier extends AbstractVerifier {
* @param certificateProvider 使
*/
protected TestVerifier(CertificateProvider certificateProvider) {
super("SHA256withRSA", certificateProvider);
super("SHA256withRSA", certificateProvider, null);
}
}

View File

@ -9,6 +9,6 @@ import com.czcb.scfs.api.core.cipher.AbstractSecretCipher;
public class AesSecretCipher extends AbstractSecretCipher {
protected AesSecretCipher() {
super("AES", "AES/GCM/NoPadding", 128);
super("AES", "AES/GCM/NoPadding", null, 128);
}
}

View File

@ -15,6 +15,6 @@ public final class RsaPrivacyDecryptor extends AbstractPrivacyDecryptor {
* @param privateKey 使
*/
public RsaPrivacyDecryptor(PrivateKey privateKey) {
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", privateKey);
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", privateKey, null);
}
}

View File

@ -16,6 +16,6 @@ public final class RsaPrivacyEncryptor extends AbstractPrivacyEncryptor {
* @param publicKey 使
*/
public RsaPrivacyEncryptor(PublicKey publicKey) {
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", publicKey);
super("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", publicKey, null);
}
}

View File

@ -14,6 +14,6 @@ public class RsaSigner extends AbstractSigner {
* @param privateKey API
*/
protected RsaSigner(PrivateKey privateKey) {
super("SHA256-WITH-RSA", "SHA256withRSA", privateKey);
super("SHA256withRSA", "SHA256withRSA", privateKey, null);
}
}

View File

@ -12,6 +12,6 @@ public class RsaVerifier extends AbstractVerifier {
* @param certificateProvider 使
*/
protected RsaVerifier(CertificateProvider certificateProvider) {
super("SHA256withRSA", certificateProvider);
super("SHA256withRSA", certificateProvider, null);
}
}

View File

@ -5,6 +5,6 @@ import com.czcb.scfs.api.core.cipher.AbstractSecretCipher;
public class TestSecretCipher extends AbstractSecretCipher {
protected TestSecretCipher() {
super("AES", "AES/GCM/NoPadding", 128);
super("AES", "AES/GCM/NoPadding", null, 128);
}
}

View File

@ -14,6 +14,6 @@ public class TestSigner extends AbstractSigner {
* @param privateKey API
*/
public TestSigner(PrivateKey privateKey) {
super("SHA256-WITH-RSA", "SHA256withRSA", privateKey);
super("SHA256withRSA", "SHA256withRSA", privateKey, null);
}
}

View File

@ -12,6 +12,6 @@ public class TestVerifier extends AbstractVerifier {
* @param certificateProvider 使
*/
public TestVerifier(CertificateProvider certificateProvider) {
super("SHA256withRSA", certificateProvider);
super("SHA256withRSA", certificateProvider, null);
}
}

View File

@ -1,6 +1,7 @@
package com.czcb.scfs.api.sm;
import com.czcb.scfs.api.core.cipher.AbstractPrivacyDecryptor;
import com.tencent.kona.KonaProvider;
import java.security.PrivateKey;
@ -17,6 +18,6 @@ public final class Sm2PrivacyDecryptor extends AbstractPrivacyDecryptor {
* @param privateKey API
*/
public Sm2PrivacyDecryptor(PrivateKey privateKey) {
super("SM2", privateKey);
super("SM2", privateKey, new KonaProvider());
}
}

View File

@ -1,6 +1,7 @@
package com.czcb.scfs.api.sm;
import com.czcb.scfs.api.core.cipher.AbstractPrivacyEncryptor;
import com.tencent.kona.KonaProvider;
import java.security.PublicKey;
@ -17,6 +18,6 @@ public final class Sm2PrivacyEncryptor extends AbstractPrivacyEncryptor {
* @param publicKey 使
*/
public Sm2PrivacyEncryptor(PublicKey publicKey) {
super("SM2", publicKey);
super("SM2", publicKey, new KonaProvider());
}
}

View File

@ -2,6 +2,7 @@ package com.czcb.scfs.api.sm;
import com.czcb.scfs.api.core.cipher.AbstractVerifier;
import com.czcb.scfs.api.core.cipher.CertificateProvider;
import com.tencent.kona.KonaProvider;
/**
* @author wangwei
@ -18,6 +19,6 @@ public class Sm2Verifier extends AbstractVerifier {
* @param certificateProvider 使
*/
public Sm2Verifier(CertificateProvider certificateProvider) {
super("SM2", certificateProvider);
super("SM3withSM2", certificateProvider, new KonaProvider());
}
}

View File

@ -1,9 +1,12 @@
package com.czcb.scfs.api.sm;
import com.czcb.scfs.api.core.cipher.AbstractSecretCipher;
import com.tencent.kona.KonaProvider;
/**
*
*
* @author wangwei
* @date 2024/2/2
*/
@ -13,6 +16,6 @@ public final class Sm4SecretCipher extends AbstractSecretCipher {
}
public Sm4SecretCipher() {
super("SM4", "SM4/GCM/NoPadding", 128);
super("SM4", "SM4/GCM/NoPadding", new KonaProvider(), 128);
}
}

View File

@ -15,6 +15,8 @@ import java.util.List;
import java.util.Objects;
/**
*
*
* @author wangwei
* @date 2024/2/2
*/
@ -67,12 +69,16 @@ public final class SmProfile extends AbstractProfile {
public SmProfile build() {
Objects.requireNonNull(this.channel);
// 证书加载器
CertificateProvider certificateProvider = new LocalCertificateProvider(certificates);
// 加密器
this.privacy = new SmPrivacy(privateKey, certificateProvider);
// 签名器
this.signature = new DefaultSignature(certificateProvider, new Sm2Signer(privateKey), new Sm2Verifier(certificateProvider));
httpProfile(httpProfile);
if (Objects.isNull(httpProfile)) {
// 创建默认的http配置
httpProfile(new DefaultHttpProfile.Builder().build());
}

View File

@ -8,6 +8,8 @@ import java.security.Security;
* KonaProvider
*/
public class SmSecurityProvider {
private SmSecurityProvider() {
}
public static void addProvider() {
if (Security.getProvider(KonaProvider.NAME) == null) {