对称加密

v1.4.1
hiparker 4 years ago
parent 04f5e7e68a
commit 73fc97db5f

@ -17,7 +17,7 @@ package opsli.plugins.crypto;
import lombok.extern.slf4j.Slf4j;
import opsli.plugins.crypto.strategy.CryptoAsymmetricService;
import opsli.plugins.crypto.strategy.impl.CryptoAsymmetricAsymmetricImpl;
import opsli.plugins.crypto.strategy.impl.CryptoAsymmetricServiceImpl;
/**
* @BelongsProject: opsli-boot
@ -30,7 +30,7 @@ import opsli.plugins.crypto.strategy.impl.CryptoAsymmetricAsymmetricImpl;
public class CryptoPlugin {
/** 非对称加密 */
private static final CryptoAsymmetricService CRYPTO_ASYMMETRIC = new CryptoAsymmetricAsymmetricImpl();
private static final CryptoAsymmetricService CRYPTO_ASYMMETRIC = new CryptoAsymmetricServiceImpl();
/**
*

@ -0,0 +1,60 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package opsli.plugins.crypto.enums;
/**
*
*
* @author Parker
* @date 202151716:48:14
*/
public enum CryptoSymmetricType {
/** 对称算法类型 */
AES("AES", "AES 算法"),
DES("DES", "DES 算法"),
DE_SEDE("DESede", "DESede 算法"),
SM4("SM4", "SM4 算法"),
;
private final String code;
private final String desc;
public static CryptoSymmetricType getCryptoType(String code) {
CryptoSymmetricType[] types = values();
for (CryptoSymmetricType type : types) {
if (type.code.equalsIgnoreCase(code)) {
return type;
}
}
return null;
}
public String getCode() {
return this.code;
}
public String getDesc() {
return this.desc;
}
// =================
CryptoSymmetricType(final String code, final String desc) {
this.code = code;
this.desc = desc;
}
}

@ -0,0 +1,36 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package opsli.plugins.crypto.model;
import lombok.Data;
import opsli.plugins.crypto.enums.CryptoSymmetricType;
/**
*
*
* @author Parker
* @date 202151715:59:52
*/
@Data
public class CryptoSymmetric {
/** 加解密类别 */
private CryptoSymmetricType cryptoType;
/** 私钥 */
private String privateKey;
}

@ -19,7 +19,7 @@ import opsli.plugins.crypto.enums.CryptoAsymmetricType;
import opsli.plugins.crypto.model.CryptoAsymmetric;
/**
*
*
*
* @author Parker
* @date 202151715:49:15

@ -0,0 +1,69 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package opsli.plugins.crypto.strategy;
import opsli.plugins.crypto.enums.CryptoAsymmetricType;
import opsli.plugins.crypto.enums.CryptoSymmetricType;
import opsli.plugins.crypto.model.CryptoAsymmetric;
import opsli.plugins.crypto.model.CryptoSymmetric;
/**
*
*
* @author Parker
* @date 202151715:49:15
*/
public interface CryptoSymmetricService {
/**
*
* @return Model
*/
CryptoSymmetric createNilModel();
/**
*
* @param cryptoSymmetricType
* @return Model
*/
CryptoSymmetric createKeyModel(final CryptoSymmetricType cryptoSymmetricType);
/**
*
* @param model
* @param data
* @return String
*/
String encrypt(final CryptoSymmetric model, final Object data);
/**
*
* @param model
* @param data
* @return Object
*/
Object decryptToObj(final CryptoSymmetric model, final String data);
/**
*
* @param model
* @param data
* @return String
*/
String decrypt(final CryptoSymmetric model, final String data);
}

@ -44,7 +44,7 @@ import java.util.concurrent.TimeUnit;
* @date 202151810:53:27
*/
@Slf4j
public class CryptoAsymmetricAsymmetricImpl implements CryptoAsymmetricService {
public class CryptoAsymmetricServiceImpl implements CryptoAsymmetricService {
/** 默认缓存个数 超出后流量自动清理 */
private static final int DEFAULT_CACHE_COUNT = 1000;
@ -232,14 +232,14 @@ public class CryptoAsymmetricAsymmetricImpl implements CryptoAsymmetricService {
return null;
}
Cache<String, AbstractAsymmetricCrypto<?>> asymmetricCryptoCache =
Cache<String, AbstractAsymmetricCrypto<?>> cryptoCache =
LFU_CACHE_MAP.get(model.getCryptoType());
AbstractAsymmetricCrypto<?> cryptoHandler = null;
try {
// 查询并设置缓存
cryptoHandler = asymmetricCryptoCache.get(model.getPublicKey(), () -> {
cryptoHandler = cryptoCache.get(model.getPublicKey(), () -> {
AbstractAsymmetricCrypto<?> tmp = null;
switch (model.getCryptoType()) {
case RSA: {

@ -0,0 +1,310 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package opsli.plugins.crypto.strategy.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.*;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import opsli.plugins.crypto.enums.CryptoSymmetricType;
import opsli.plugins.crypto.exception.CryptoException;
import opsli.plugins.crypto.model.CryptoSymmetric;
import opsli.plugins.crypto.msg.CryptoMsg;
import opsli.plugins.crypto.strategy.CryptoSymmetricService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
*
*
* @author Parker
* @date 202151810:53:27
*/
@Slf4j
public class CryptoSymmetricServiceImpl implements CryptoSymmetricService {
/** 默认缓存个数 超出后流量自动清理 */
private static final int DEFAULT_CACHE_COUNT = 1000;
/** 默认缓存时效 超出后自动清理 */
private static final int DEFAULT_CACHE_TIME = 20;
/** 加解密执行器缓存 防止多次创建 */
private static final Map<CryptoSymmetricType, Cache<String, SymmetricCrypto>> LFU_CACHE_MAP;
static{
// 初始化缓存类对象
LFU_CACHE_MAP = Maps.newConcurrentMap();
for (CryptoSymmetricType asymmetricType : CryptoSymmetricType.values()) {
LFU_CACHE_MAP.put(asymmetricType,
CacheBuilder
.newBuilder().maximumSize(DEFAULT_CACHE_COUNT)
.expireAfterWrite(DEFAULT_CACHE_TIME, TimeUnit.MINUTES).build()
);
}
}
/**
*
* @return Model
*/
@Override
public CryptoSymmetric createNilModel() {
return new CryptoSymmetric();
}
/**
*
* @param cryptoSymmetricType
* @return Model
*/
@Override
public CryptoSymmetric createKeyModel(final CryptoSymmetricType cryptoSymmetricType){
SymmetricCrypto cryptoHandler =
this.createCryptoHandler(cryptoSymmetricType);
CryptoSymmetric model = this.createNilModel();
if(cryptoHandler != null){
SecretKey secretKey = cryptoHandler.getSecretKey();
String privateKey = Base64.encode(secretKey.getEncoded());
model.setCryptoType(cryptoSymmetricType);
model.setPrivateKey(privateKey);
}
return model;
}
/**
*
* @param model
* @param data
* @return String
*/
@Override
public String encrypt(final CryptoSymmetric model, final Object data){
// 非法验证
this.verify(model);
// 原始/加密 数据
String encryptedStr;
try {
encryptedStr = JSONUtil.toJsonStr(data);
// 创建执行器
SymmetricCrypto cryptoHandler =
this.createCryptoHandler(model);
if(cryptoHandler == null){
// 无法获得加解密执行器
throw new CryptoException(CryptoMsg.CRYPTO_EXCEPTION_HANDLER_NULL);
}
// 执行加密操作
encryptedStr = cryptoHandler.encryptBase64(StrUtil.bytes(encryptedStr, CharsetUtil.CHARSET_UTF_8));
}catch (JSONException jse){
// 加密数据转换Json失败
throw new CryptoException(CryptoMsg.CRYPTO_EXCEPTION_TO_JSON);
}catch (CryptoException ce){
// 如果检测到已有异常 则直接抛出
throw ce;
}catch (Exception e){
log.error(e.getMessage(), e);
// 加密失败
throw new CryptoException(CryptoMsg.CRYPTO_EXCEPTION_EN);
}
return encryptedStr;
}
/**
* - Obj
* @param model
* @param data
* @return Object
*/
@Override
public Object decryptToObj(final CryptoSymmetric model, final String data){
Object obj;
// 解密数据
String decryptedData = decrypt(model, data);
// 反射对象
try{
obj = JSONUtil.parse(decryptedData);
}catch (Exception e){
// 非对称解密反射失败
throw new CryptoException(CryptoMsg.CRYPTO_EXCEPTION_REFLEX);
}
return obj;
}
/**
*
* @param model
* @param data
* @return String
*/
@Override
public String decrypt(final CryptoSymmetric model, final String data){
// 非法验证
this.verify(model);
// 如果解密内容为空 则返回原内容
if(StringUtils.isEmpty(data)){
return data;
}
String decryptStr;
try {
// 创建执行器
SymmetricCrypto cryptoHandler =
this.createCryptoHandler(model);
if(cryptoHandler == null){
// 无法获得加解密执行器
throw new CryptoException(CryptoMsg.CRYPTO_EXCEPTION_HANDLER_NULL);
}
// 处理数据
String currData = data.replaceAll(" ", "+");
// 解密数据 - 返回Json 格式String
decryptStr = cryptoHandler.decryptStr(currData, CharsetUtil.CHARSET_UTF_8);
}catch (CryptoException ce){
// 如果检测到已有异常 则直接抛出
throw ce;
}catch (Exception e){
// 解密失败
throw new CryptoException(CryptoMsg.CRYPTO_EXCEPTION_DE);
}
return decryptStr;
}
/**
*
* @param model
*/
private void verify(CryptoSymmetric model){
// 非法验证
if(model == null ||
model.getCryptoType() == null ||
StringUtils.isEmpty(model.getPrivateKey())
){
// 配置信息未初始化
throw new CryptoException(CryptoMsg.CRYPTO_EXCEPTION_MODEL_NULL);
}
}
/**
*
* 使
*
* @param model
* @return
*/
private SymmetricCrypto createCryptoHandler(final CryptoSymmetric model){
// 非法验证
if(model == null ||
model.getCryptoType() == null ||
StringUtils.isEmpty(model.getPrivateKey())
){
return null;
}
Cache<String, SymmetricCrypto> cryptoCache =
LFU_CACHE_MAP.get(model.getCryptoType());
SymmetricCrypto cryptoHandler = null;
try {
// 查询并设置缓存
cryptoHandler = cryptoCache.get(model.getPrivateKey(), () -> {
SymmetricCrypto tmp = null;
byte[] keyBytes = Base64.decode(model.getPrivateKey());
switch (model.getCryptoType()) {
case AES:{
tmp = SecureUtil.aes(keyBytes);
break;
}
case DES:{
tmp = SecureUtil.des(keyBytes);
break;
}
case DE_SEDE:{
tmp = SecureUtil.desede(keyBytes);
break;
}
case SM4:{
tmp = SmUtil.sm4(keyBytes);
break;
}
default:
break;
}
return tmp;
});
}catch (ExecutionException e){
log.error(e.getMessage(), e);
}
return cryptoHandler;
}
/**
*
* @param cryptoSymmetricType
* @return Model
*/
private SymmetricCrypto createCryptoHandler(final CryptoSymmetricType cryptoSymmetricType){
SymmetricCrypto cryptoHandler = null;
switch (cryptoSymmetricType){
case AES:{
cryptoHandler = SecureUtil.aes();
break;
}
case DES:{
cryptoHandler = SecureUtil.des();
break;
}
case DE_SEDE:{
cryptoHandler = SecureUtil.desede();
break;
}
case SM4:{
cryptoHandler = SmUtil.sm4();
break;
}
default:
break;
}
return cryptoHandler;
}
}
Loading…
Cancel
Save