8 changed files with 293 additions and 19 deletions
@ -1,5 +1,5 @@ |
|||
|
|||
package com.epmet.utils; |
|||
package com.epmet.commons.tools.utils.api.yt; |
|||
|
|||
import lombok.Data; |
|||
|
@ -0,0 +1,199 @@ |
|||
package com.epmet.commons.tools.utils.api.yt; |
|||
|
|||
import com.fasterxml.jackson.core.JsonProcessingException; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import org.apache.commons.codec.binary.Base64; |
|||
import org.bouncycastle.jce.provider.BouncyCastleProvider; |
|||
|
|||
import javax.crypto.BadPaddingException; |
|||
import javax.crypto.Cipher; |
|||
import javax.crypto.IllegalBlockSizeException; |
|||
import javax.crypto.SecretKey; |
|||
import javax.crypto.spec.SecretKeySpec; |
|||
import java.nio.charset.Charset; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.security.InvalidKeyException; |
|||
import java.security.Security; |
|||
|
|||
/** |
|||
* 烟台的认证中心-国密sm4加解密 |
|||
*/ |
|||
public class SM4UtilsForYanTai { |
|||
private static String SM4_KEY = "yaweisoftware@xy"; |
|||
//编码格式
|
|||
private static final Charset encryptCharset = StandardCharsets.UTF_8; |
|||
|
|||
public enum Algorithm { |
|||
SM4("SM4","SM4","国密四,key长16byte"); |
|||
private String keyAlgorithm; |
|||
private String transformation; |
|||
private String description;//描述
|
|||
Algorithm(String keyAlgorithm, String transformation, String description) { |
|||
this.keyAlgorithm = keyAlgorithm; |
|||
this.transformation = transformation; |
|||
this.description = description; |
|||
} |
|||
public String getKeyAlgorithm() { |
|||
return this.keyAlgorithm; |
|||
} |
|||
public String getTransformation() { |
|||
return this.transformation; |
|||
} |
|||
public String getDescription() { |
|||
return this.description; |
|||
} |
|||
} |
|||
|
|||
private static final String PROVIDER_NAME = "BC"; |
|||
static { |
|||
Security.addProvider(new BouncyCastleProvider()); |
|||
} |
|||
|
|||
/** |
|||
* 自定字符串产生密钥 |
|||
* @param algorithm 加解密算法 |
|||
* @param keyStr 密钥字符串 |
|||
* @param charset 编码字符集 |
|||
* @return 密钥 |
|||
*/ |
|||
public static SecretKey genKeyByStr(Algorithm algorithm, String keyStr, Charset charset) { |
|||
return readKeyFromBytes(algorithm, keyStr.getBytes(charset)); |
|||
} |
|||
|
|||
/** |
|||
* 根据指定字节数组产生密钥 |
|||
* @param algorithm 加解密算法 |
|||
* @param keyBytes 密钥字节数组 |
|||
* @return 密钥 |
|||
*/ |
|||
public static SecretKey readKeyFromBytes(Algorithm algorithm, byte[] keyBytes) { |
|||
return new SecretKeySpec(keyBytes, algorithm.getKeyAlgorithm()); |
|||
} |
|||
|
|||
/****************************加密*********************************/ |
|||
/** |
|||
* 加密字符串,并进行base64编码 |
|||
* @param algorithm 加解密算法 |
|||
* @param key 密钥 |
|||
* @param data 明文 |
|||
* @param charset 编码字符集 |
|||
* @return 密文 |
|||
* @throws InvalidKeyException 密钥错误 |
|||
*/ |
|||
public static String encryptBase64(Algorithm algorithm, SecretKey key, String data, Charset charset) throws InvalidKeyException { |
|||
return Base64.encodeBase64String(encrypt(algorithm, key, data.getBytes(charset))); |
|||
} |
|||
|
|||
/** |
|||
* 加密字节数组 |
|||
* @param algorithm 加解密算法 |
|||
* @param key 密钥 |
|||
* @param data 明文 |
|||
* @return 密文 |
|||
* @throws InvalidKeyException 密钥错误 |
|||
*/ |
|||
public static byte[] encrypt(Algorithm algorithm, SecretKey key, byte[] data) throws InvalidKeyException { |
|||
try { |
|||
return cipherDoFinal(algorithm, Cipher.ENCRYPT_MODE, key, data); |
|||
} catch (BadPaddingException e) { |
|||
throw new RuntimeException(e);//明文没有具体格式要求,不会出错。所以这个异常不需要外部捕获。
|
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 加解密字节数组 |
|||
* @param algorithm 加解密算法 |
|||
* @param opmode 操作:1加密,2解密 |
|||
* @param key 密钥 |
|||
* @param data 数据 |
|||
* @throws InvalidKeyException 密钥错误 |
|||
* @throws BadPaddingException 解密密文错误(加密模式没有) |
|||
*/ |
|||
private static byte[] cipherDoFinal(Algorithm algorithm, int opmode, SecretKey key, byte[] data) throws InvalidKeyException, BadPaddingException { |
|||
Cipher cipher; |
|||
try { |
|||
cipher = Cipher.getInstance(algorithm.getTransformation(), PROVIDER_NAME); |
|||
} catch (Exception e) { |
|||
//NoSuchAlgorithmException:加密算法名是本工具类提供的,如果错了业务没有办法处理。所以这个异常不需要外部捕获。
|
|||
//NoSuchProviderException:Provider是本工具类提供的,如果错了业务没有办法处理。所以这个异常不需要外部捕获。
|
|||
//NoSuchPaddingException:没有特定的填充机制,与环境有关,业务没有办法处理。所以这个异常不需要外部捕获。
|
|||
throw new RuntimeException(e); |
|||
} |
|||
cipher.init(opmode, key); |
|||
try { |
|||
return cipher.doFinal(data); |
|||
} catch (IllegalBlockSizeException e) { |
|||
throw new RuntimeException(e);//业务不需要将数据分块(好像由底层处理了),如果错了业务没有办法处理。所以这个异常不需要外部捕获。
|
|||
} |
|||
} |
|||
|
|||
/****************************解密*********************************/ |
|||
/** |
|||
* 对字符串先进行base64解码,再解密 |
|||
* @param algorithm 加解密算法 |
|||
* @param key 密钥 |
|||
* @param data 密文 |
|||
* @param charset 编码字符集 |
|||
* @return 明文 |
|||
* @throws InvalidKeyException 密钥错误 |
|||
* @throws BadPaddingException 密文错误 |
|||
*/ |
|||
public static String decryptBase64(Algorithm algorithm, SecretKey key, String data, Charset charset) |
|||
throws InvalidKeyException, BadPaddingException { |
|||
return new String(decrypt(algorithm, key, Base64.decodeBase64(data)), charset); |
|||
} |
|||
|
|||
/** |
|||
* 解密字节数组 |
|||
* @param algorithm 加解密算法 |
|||
* @param key 密钥 |
|||
* @param data 密文 |
|||
* @return 明文 |
|||
* @throws InvalidKeyException 密钥错误 |
|||
* @throws BadPaddingException 密文错误 |
|||
*/ |
|||
public static byte[] decrypt(Algorithm algorithm, SecretKey key, byte[] data) throws InvalidKeyException, BadPaddingException { |
|||
return cipherDoFinal(algorithm, Cipher.DECRYPT_MODE, key, data); |
|||
} |
|||
|
|||
public static String Encrypt(String data) throws InvalidKeyException { |
|||
SecretKey key = genKeyByStr(Algorithm.SM4, SM4_KEY, encryptCharset); |
|||
return encryptBase64(Algorithm.SM4, key, data, encryptCharset); |
|||
} |
|||
public static String Decrypt(String data) throws BadPaddingException, InvalidKeyException { |
|||
SecretKey key = genKeyByStr(Algorithm.SM4, SM4_KEY, encryptCharset); |
|||
return decryptBase64(Algorithm.SM4, key, data, encryptCharset); |
|||
} |
|||
//加密
|
|||
public static String dealEncryptData(Object data) throws JsonProcessingException, InvalidKeyException { |
|||
ObjectMapper objectMapper = new ObjectMapper(); |
|||
String dataString = ""; |
|||
try { |
|||
if(data instanceof String){ |
|||
dataString = (String) data; |
|||
}else { |
|||
dataString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(data); |
|||
} |
|||
String dataEncrypt = Encrypt(dataString); |
|||
return dataEncrypt; |
|||
}catch (Exception e){ |
|||
return dataString; |
|||
} |
|||
} |
|||
//解密
|
|||
public static String dealDecryptData(Object data) throws JsonProcessingException, BadPaddingException, InvalidKeyException { |
|||
String dataString = ""; |
|||
try { |
|||
ObjectMapper objectMapper = new ObjectMapper(); |
|||
if (data instanceof String) { |
|||
dataString = (String) data; |
|||
} else { |
|||
dataString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(data); |
|||
} |
|||
String dataDecrypt = Decrypt(dataString); |
|||
return dataDecrypt; |
|||
}catch (Exception e){ |
|||
return dataString; |
|||
} |
|||
} |
|||
} |
@ -1,5 +1,5 @@ |
|||
|
|||
package com.epmet.utils; |
|||
package com.epmet.commons.tools.utils.api.yt; |
|||
|
|||
import lombok.Data; |
|||
|
Loading…
Reference in new issue