All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edi.rule.config.JSRuleSecurity Maven / Gradle / Ivy

package edi.rule.config;

import edi.rule.util.ZSString;
import edi.rule.work.custom.JSRuleException;
import edi.rule.work.enums.JSRuleSecurityEnum;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.function.BiFunction;
import java.util.function.Consumer;

/**
 * @author 摩拉克斯
 * 

*/ @Slf4j public class JSRuleSecurity { private static final String provider = "BC"; static { Security.addProvider(new BouncyCastleProvider()); } /** *

判断当前系统是否是安全模式,true是,false不是 * @param type 待判断的安全模式 * */ public static boolean isSecurityMode(JSRuleSecurityEnum type){ return JSRuleSecurityEnum.NONE != type; } /** *

判断当前系统是否是安全模式,true是,false不是 * */ public static boolean isSecurityMode(){ return isSecurityMode(JSRuleContext.getSecurity()); } /** *

获取签名原文,后台配置的秘钥与文本进行组合 * @param plainText 文本 * @return 返回组合后的签名文本 * */ public static String joinSignKey(String plainText){ if (ZSString.isBlank(JSRuleContext.getProperties().security.signKey)){ return plainText; } return plainText+JSRuleContext.getProperties().security.signKey; } /*--------------------------------AES--------------------------------*/ public static String aesEncrypt(String plainText){ try { return Base64.getEncoder().encodeToString(getAESCipher(Cipher.ENCRYPT_MODE).doFinal(plainText.getBytes(StandardCharsets.UTF_8))); } catch (IllegalBlockSizeException | BadPaddingException e) { throw new JSRuleException(e); } } public static String aesDecrypt(String encryptText) { try { return new String(getAESCipher(Cipher.DECRYPT_MODE).doFinal(Base64.getDecoder().decode(encryptText))); } catch (IllegalBlockSizeException | BadPaddingException e) { throw new JSRuleException(e); } } public static SecretKey aesGenerate(){ return AESParam.keyGenerator.generateKey(); } public static String aesGenerateStr(){ return Base64.getEncoder().encodeToString(aesGenerate().getEncoded()); } static void initAES(String secretKey,String vector){ AESParam.secretKey = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8),AESParam.keyInstance); AESParam.ivSpec = new IvParameterSpec(vector.getBytes(StandardCharsets.UTF_8)); } private static final class AESParam { private static final String algorithm = "AES/CBC/PKCS5Padding"; private static final String keyInstance = "AES"; private static final KeyGenerator keyGenerator; private static IvParameterSpec ivSpec; private static SecretKeySpec secretKey; static{ try { keyGenerator = KeyGenerator.getInstance(keyInstance); keyGenerator.init(128); } catch (NoSuchAlgorithmException e) { throw new JSRuleException(e); } } } private static Cipher getAESCipher(int mode){ try { Cipher cipher = Cipher.getInstance(AESParam.algorithm); cipher.init(mode,AESParam.secretKey,AESParam.ivSpec); return cipher; } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException e) { throw new JSRuleException(e); } } /*--------------------------------SM2--------------------------------*/ /** *

公钥加密 * @param plainText 原文 * */ public static String sm2Encrypt(String plainText) { return base64Encrypt(plainText,SM2Param.publicKey,getCipher(SM2Param.transformation),(d,c)->{ try { return c.doFinal(d); } catch (IllegalBlockSizeException | BadPaddingException e) { throw new JSRuleException(e); } }); } /** *

私钥解密 * @param encryptText 为公钥加密密文 * */ public static String sm2Decrypt(String encryptText) { return base64Decrypt(encryptText,SM2Param.privateKey,getCipher(SM2Param.transformation),(d,c)->{ try { return c.doFinal(d); } catch (IllegalBlockSizeException | BadPaddingException e) { throw new JSRuleException(e); } }); } /** *

私钥签名 * @param text 文本 * */ public static String sm2Sign(String text) { return base64Sign(joinSignKey(text),SM2Param.privateKey,SM2Param.algorithm); } public static String sm2Sign(String text, String signKey) { return base64Sign(text+signKey,SM2Param.privateKey,SM2Param.algorithm); } /** *

公钥验签,自动取后台配置的秘钥对原文文本进行组合,得到组合文本后再与签名后的密文进行比对验签 * @param text 待做校验的原文文本,可以是密文也可以不是 * @param signText 需要比对验证的签名文本(进行签名算法后得到的文本) * @return true校验签名通过,false校验签名不通过 * */ public static boolean sm2Verify(String text,String signText) { return base64Verify(joinSignKey(text),signText,SM2Param.publicKey,SM2Param.algorithm); } public static boolean sm2Verify(String text,String signKey,String signText) { return base64Verify(text+signKey,signText,SM2Param.publicKey,SM2Param.algorithm); } /** *

生成sm2秘钥对儿 * */ public static KeyPair sm2Generate() { try{ // 实例化KeyPairGenerator对象,并指定算法为EC(椭圆曲线),提供者为BC(Bouncy Castle) KeyPairGenerator kpg = KeyPairGenerator.getInstance(SM2Param.keyInstance, provider); //设置椭圆曲线参数为sm2p256v1,这是SM2算法所使用的特定椭圆曲线,初始化KeyPairGenerator对象,使用随机数生成器以增加密钥的随机性 kpg.initialize(new ECGenParameterSpec("sm2p256v1"), new SecureRandom()); return kpg.generateKeyPair(); } catch (Exception e) { throw new JSRuleException(e); } } /** *

初始化SM2对象 * */ static void initSM2(String pubQKeyBase64,String prvDKeyBase64){ SM2Param.pubQKeyBase64 = pubQKeyBase64; SM2Param.prvDKeyBase64 = prvDKeyBase64; SM2Param.publicKey = initPublicKey(SM2Param.pubQKeyBase64,SM2Param.keyFactory); SM2Param.privateKey = initPrivateKey(SM2Param.prvDKeyBase64,SM2Param.keyFactory); } private static final class SM2Param { private static final String algorithm = "SM3withSM2"; private static final String transformation = "SM2"; private static final String keyInstance = "EC"; private static final KeyFactory keyFactory; private static String pubQKeyBase64; private static String prvDKeyBase64; private static PublicKey publicKey; private static PrivateKey privateKey; static { try { keyFactory = KeyFactory.getInstance(SM2Param.keyInstance, new BouncyCastleProvider()); } catch (Exception e) { throw new JSRuleException(e); } } } /*--------------------------------RSA--------------------------------*/ public static String rsaEncrypt(String plainText) { return base64Encrypt(plainText,RSAParam.publicKey,getCipher(RSAParam.transformation), JSRuleSecurity::rsaEncryptSection); } public static String rsaDecrypt(String encryptText) { return base64Decrypt(encryptText,RSAParam.privateKey,getCipher(RSAParam.transformation), JSRuleSecurity::rsaDecryptSection); } private static byte[] rsaEncryptSection(byte[] data,Cipher cipher){ return writeRsaSection(data,cipher,RSAParam.rsaEncryptSize); } private static byte[] rsaDecryptSection(byte[] data,Cipher cipher){ return writeRsaSection(data,cipher,RSAParam.rsaDecryptSize); } private static byte[] writeRsaSection(byte[] data,Cipher cipher,int size){ try(ByteArrayOutputStream out = new ByteArrayOutputStream()){ int length = data.length;int offSet = 0;byte[] cache;int i = 0; while (length - offSet > 0) { if (length - offSet > size) { cache = cipher.doFinal(data, offSet, size); } else { cache = cipher.doFinal(data, offSet, length - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * size; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } catch (IOException | IllegalBlockSizeException | BadPaddingException e) { throw new JSRuleException(e); } } public static String rsaSign(String text) { return base64Sign(joinSignKey(text),RSAParam.privateKey,RSAParam.algorithm); } public static String rsaSign(String text,String signKey) { return base64Sign(text+signKey,RSAParam.privateKey,RSAParam.algorithm); } public static boolean rsaVerify(String text,String signText) { return base64Verify(joinSignKey(text),signText,RSAParam.publicKey,RSAParam.algorithm); } public static boolean rsaVerify(String text,String signKey,String signText) { return base64Verify(text+signKey,signText,RSAParam.publicKey,RSAParam.algorithm); } public static KeyPair rsaGenerate() { try{ KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSAParam.keyInstance, provider); kpg.initialize(RSAParam.rsaKeySize); return kpg.generateKeyPair(); } catch (Exception e) { throw new JSRuleException(e); } } static void initRSA(String pubQKeyBase64,String prvDKeyBase64){ RSAParam.pubQKeyBase64 = pubQKeyBase64; RSAParam.prvDKeyBase64 = prvDKeyBase64; RSAParam.publicKey = initPublicKey(RSAParam.pubQKeyBase64,RSAParam.keyFactory); RSAParam.privateKey = initPrivateKey(RSAParam.prvDKeyBase64,RSAParam.keyFactory); } private static final class RSAParam { private static final String algorithm = "SHA256withRSA"; //PKCS1Padding通常用于非对称加密,PKCS5Padding通常用于对称加密 private static final String transformation = "RSA"; private static final String keyInstance = "RSA"; private static final KeyFactory keyFactory; private static String pubQKeyBase64; private static String prvDKeyBase64; private static PublicKey publicKey; private static PrivateKey privateKey; private static final int rsaKeySize = JSRuleContext.getProperties().security.rsaKeySize; private static final int rsaDecryptSize = rsaKeySize/8; private static final int rsaEncryptSize = rsaDecryptSize-1; static { try { keyFactory = KeyFactory.getInstance(RSAParam.keyInstance); } catch (Exception e) { throw new JSRuleException(e); } } } /*由于Cipher是有状态的,因此每次加解密都需要重新创建Cipher对象*/ private static Cipher getCipher(String transformation){ try { return Cipher.getInstance(transformation,provider); } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException e) { throw new JSRuleException(e); } } private static String base64Encrypt(String plainText,Key key,Cipher cipher,BiFunction doFinal) { return Base64.getEncoder().encodeToString(encrypt(plainText.getBytes(StandardCharsets.UTF_8),key,cipher,doFinal)); } private static String base64Decrypt(String encryptText,Key key,Cipher cipher,BiFunction doFinal) { return new String(decrypt(Base64.getDecoder().decode(encryptText),key,cipher,doFinal)); } private static String base64Sign(String text,PrivateKey privateKey,String algorithm) { return Base64.getEncoder().encodeToString(sign(text.getBytes(StandardCharsets.UTF_8),privateKey,algorithm)); } private static boolean base64Verify(String text,String signText,PublicKey publicKey,String algorithm) { return verify(text,Base64.getDecoder().decode(signText),publicKey,algorithm); } private static PublicKey initPublicKey(String pubQKeyBase64,KeyFactory keyFactory) { try { return keyFactory.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(pubQKeyBase64))); } catch (InvalidKeySpecException e) { throw new JSRuleException(e); } } private static PrivateKey initPrivateKey(String prvDKeyBase64,KeyFactory keyFactory) { try { return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(prvDKeyBase64))); } catch (InvalidKeySpecException e) { throw new JSRuleException(e); } } private static byte[] cipherFinal(byte[] data, int mode, Key key, Cipher cipher,BiFunction doFinal){ try{ cipher.init(mode, key); }catch (Exception e){ throw new JSRuleException(e); } return doFinal.apply(data,cipher); } private static byte[] encrypt(byte[] data,Key key, Cipher cipher, BiFunction doFinal) { return cipherFinal(data,Cipher.ENCRYPT_MODE, key,cipher,doFinal); } private static byte[] decrypt(byte[] encryptData,Key key,Cipher cipher, BiFunction doFinal) { return cipherFinal(encryptData,Cipher.DECRYPT_MODE, key,cipher,doFinal); } private static byte[] sign(byte[] data,PrivateKey privateKey,String algorithm) { try { return getSignature(data,signature->{ try { signature.initSign(privateKey); } catch (InvalidKeyException e) { throw new JSRuleException(e); } },algorithm).sign(); } catch (SignatureException e) { throw new JSRuleException(e); } } private static boolean verify(String data, byte[] signatureBytes,PublicKey publicKey,String algorithm) { try { return getSignature(data.getBytes(StandardCharsets.UTF_8),signature->{ try { signature.initVerify(publicKey); } catch (InvalidKeyException e) { throw new JSRuleException(e); } },algorithm).verify(signatureBytes); } catch (SignatureException e) { throw new JSRuleException(e.getMessage()); } } private static Signature getSignature(byte[] data, Consumer behavior,String algorithm) { try{ // 初始化签名对象,指定使用SM3withSM2算法和BC提供者。 Signature signature = Signature.getInstance(algorithm, provider); behavior.accept(signature); signature.update(data); return signature; } catch (Exception e) { throw new JSRuleException(e.getMessage()); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy